summaryrefslogtreecommitdiff
path: root/src/battle/battle_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/battle/battle_util.c')
-rw-r--r--src/battle/battle_util.c3549
1 files changed, 0 insertions, 3549 deletions
diff --git a/src/battle/battle_util.c b/src/battle/battle_util.c
deleted file mode 100644
index 3d1770239..000000000
--- a/src/battle/battle_util.c
+++ /dev/null
@@ -1,3549 +0,0 @@
-#include "global.h"
-#include "battle.h"
-#include "battle_util.h"
-#include "data2.h"
-#include "event_data.h"
-#include "ewram.h"
-#include "field_weather.h"
-#include "item.h"
-#include "link.h"
-#include "pokemon.h"
-#include "random.h"
-#include "rom_8077ABC.h"
-#include "string_util.h"
-#include "text.h"
-#include "util.h"
-#include "constants/abilities.h"
-#include "constants/battle_move_effects.h"
-#include "constants/flags.h"
-#include "constants/hold_effects.h"
-#include "constants/items.h"
-#include "constants/moves.h"
-#include "constants/species.h"
-#include "constants/weather.h"
-
-extern u8 gUnknown_02023A14_50;
-
-extern const u8* gBattlescriptCurrInstr;
-extern u8 gActiveBattler;
-extern u8 gBattleBufferB[4][0x200];
-extern u8* gSelectionBattleScripts[4]; //battlescript location when you try to choose a move you're not allowed to
-extern u16 gLastUsedMove[4];
-extern struct BattlePokemon gBattleMons[4];
-extern struct BattleEnigmaBerry gEnigmaBerries[4];
-extern u8 gStringBank;
-extern u16 gLastUsedItem;
-extern u16 gCurrentMove;
-extern const u32 gBitTable[];
-extern u16 gBattleTypeFlags;
-extern u8 gBattlersCount;
-extern u32 gStatuses3[4];
-extern u8 gBankAttacker;
-extern u8 gBankTarget;
-extern u8 gBanksByTurnOrder[4];
-extern u16 gSideAffecting[2];
-extern u16 gBattleWeather;
-extern void (*gBattleMainFunc)(void);
-extern u8 gAbsentBattlerFlags;
-extern u8 gBattleCommunication[];
-extern u32 gHitMarker;
-extern u8 gEffectBank;
-extern u8 gBank1;
-extern s32 gBattleMoveDamage;
-extern u16 gBattlerPartyIndexes[4];
-extern u16 gChosenMovesByBanks[4];
-extern s32 gTakenDmg[4];
-extern u8 gTakenDmgBanks[4];
-extern u8 gMoveResultFlags;
-extern u8 gLastUsedAbility;
-extern u8 gBattleTextBuff2[];
-extern u8 gCurrentActionFuncId;
-extern struct BattleEnigmaBerry gEnigmaBerries[4];
-extern u8 gUnknown_02024BE5;
-extern u8 gCurrMovePos;
-extern u16 gRandomMove;
-extern s32 gBattleMoveDamage;
-extern u16 gDynamicBasePower;
-extern u32 gBattleExecBuffer;
-extern u8 gSentPokesToOpponent[2];
-extern const u16 gSoundMovesTable[];
-extern const u8 gStatusConditionString_PoisonJpn[];
-extern const u8 gStatusConditionString_SleepJpn[];
-extern const u8 gStatusConditionString_ParalysisJpn[];
-extern const u8 gStatusConditionString_BurnJpn[];
-extern const u8 gStatusConditionString_IceJpn[];
-extern const u8 gStatusConditionString_ConfusionJpn[];
-extern const u8 gStatusConditionString_LoveJpn[];
-extern const BattleCmdFunc gBattleScriptingCommandsTable[];
-
-u8 IsImprisoned(u8 bank, u16 move);
-u8 GetBattlerAtPosition(u8 ID);
-u8 GetBattlerPosition(u8 bank);
-u8 GetBattlerSide(u8 bank);
-void SetMoveEffect(bool8 primary, u8 certainArg);
-bool8 UproarWakeUpCheck(u8 bank);
-bool8 sub_8018018(u8 bank, u8, u8);
-s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 bank_atk, u8 bank_def);
-u8 CountTrailingZeroBits(u32 a);
-u8 GetMoveTarget(u16 move, u8 useMoveTarget);
-u8 sub_803FC34(u8 bank);
-u16 sub_803FBFC(u8 a);
-void RecordAbilityBattle(u8 bank, u8 ability);
-void RecordItemBattle(u8 bank, u8 holdEffect);
-s8 GetPokeFlavourRelation(u32 pid, u8 flavor);
-
-extern u8 BattleScript_MoveSelectionDisabledMove[];
-extern u8 BattleScript_MoveSelectionTormented[];
-extern u8 BattleScript_MoveSelectionTaunted[];
-extern u8 BattleScript_MoveSelectionImprisoned[];
-extern u8 BattleScript_MoveSelectionChoiceBanded[];
-extern u8 BattleScript_MoveSelectionNoPP[];
-extern u8 BattleScript_NoMovesLeft[];
-extern u8 BattleScript_WishComesTrue[];
-extern u8 BattleScript_IngrainTurnHeal[];
-extern u8 BattleScript_LeechSeedTurnDrain[];
-extern u8 BattleScript_PoisonTurnDmg[];
-extern u8 BattleScript_BurnTurnDmg[];
-extern u8 BattleScript_NightmareTurnDmg[];
-extern u8 BattleScript_CurseTurnDmg[];
-extern u8 BattleScript_WrapTurnDmg[];
-extern u8 BattleScript_WrapEnds[];
-extern u8 BattleScript_DisabledNoMore[];
-extern u8 BattleScript_EncoredNoMore[];
-
-extern u8 BattleScript_SideStatusWoreOff[];
-extern u8 BattleScript_RainContinuesOrEnds[];
-extern u8 BattleScript_SandStormHailEnds[];
-extern u8 BattleScript_DamagingWeatherContinues[];
-extern u8 BattleScript_SunlightFaded[];
-extern u8 BattleScript_SunlightContinues[];
-extern u8 BattleScript_SafeguardEnds[];
-extern u8 BattleScript_MonWokeUpInUproar[]; //uproar wakeup BS
-extern u8 BattleScript_PrintUproarOverTurns[]; //uproar BS
-extern u8 BattleScript_ThrashConfuses[];
-extern u8 BattleScript_YawnMakesAsleep[];
-extern u8 BattleScript_MonTookFutureAttack[];
-extern u8 BattleScript_PerishSongHits[];
-extern u8 BattleScript_PerishSongTimerGoesDown[];
-extern u8 BattleScript_GiveExp[];
-extern u8 BattleScript_HandleFaintedMon[];
-
-extern u8 BattleScript_MoveUsedIsAsleep[];
-extern u8 BattleScript_MoveUsedWokeUp[];
-extern u8 BattleScript_MoveUsedIsFrozen[];
-extern u8 BattleScript_MoveUsedUnfroze[];
-extern u8 BattleScript_MoveUsedLoafingAround[];
-extern u8 BattleScript_MoveUsedMustRecharge[];
-extern u8 BattleScript_MoveUsedFlinched[];
-extern u8 BattleScript_MoveUsedIsDisabled[];
-extern u8 BattleScript_MoveUsedIsTaunted[];
-extern u8 BattleScript_MoveUsedIsImprisoned[];
-extern u8 BattleScript_MoveUsedIsConfused[];
-extern u8 BattleScript_MoveUsedIsConfusedNoMore[];
-extern u8 BattleScript_MoveUsedIsParalyzed[];
-extern u8 BattleScript_MoveUsedIsParalyzedCantAttack[];
-extern u8 BattleScript_MoveUsedIsInLove[];
-extern u8 BattleScript_BideStoringEnergy[];
-extern u8 BattleScript_BideAttack[];
-extern u8 BattleScript_BideNoEnergyToAttack[];
-
-extern u8 BattleScript_OverworldWeatherStarts[]; //load weather from overworld
-extern u8 BattleScript_DrizzleActivates[];
-extern u8 BattleScript_SandstreamActivates[];
-extern u8 BattleScript_DroughtActivates[];
-extern u8 BattleScript_CastformChange[];
-extern u8 BattleScript_RainDishActivates[];
-extern u8 BattleScript_ShedSkinActivates[];
-extern u8 BattleScript_SpeedBoostActivates[];
-extern u8 BattleScript_SoundproofProtected[];
-extern u8 BattleScript_MoveHPDrain[];
-extern u8 BattleScript_MoveHPDrain_PPLoss[];
-extern u8 BattleScript_FlashFireBoost[];
-extern u8 BattleScript_FlashFireBoost_PPLoss[];
-extern u8 BattleScript_MoveHPDrain_FullHP[];
-extern u8 BattleScript_MoveHPDrain_FullHP_PPLoss[];
-extern u8 BattleScript_ColorChangeActivates[];
-extern u8 BattleScript_RoughSkinActivates[];
-extern u8 BattleScript_ApplySecondaryEffect[];
-extern u8 BattleScript_CuteCharmActivates[];
-extern u8 BattleScript_AbilityCuredStatus[]; //ability status clear
-extern u8 BattleScript_SynchronizeActivates[];
-extern u8 gUnknown_081D978C[]; //intimidate1
-extern u8 gUnknown_081D9795[]; //intimidate2
-extern u8 BattleScript_TraceActivates[];
-
-extern u8 BattleScript_WhiteHerbEnd2[];
-extern u8 BattleScript_WhiteHerbRet[];
-extern u8 BattleScript_ItemHealHP_RemoveItem[];
-extern u8 BattleScript_BerryPPHealEnd2[];
-extern u8 BattleScript_ItemHealHP_End2[];
-extern u8 BattleScript_BerryConfuseHealEnd2[];
-extern u8 BattleScript_BerryStatRaiseEnd2[];
-extern u8 BattleScript_BerryFocusEnergyEnd2[];
-extern u8 BattleScript_BerryCurePrlzEnd2[];
-extern u8 BattleScript_BerryCurePsnEnd2[];
-extern u8 BattleScript_BerryCureBrnEnd2[];
-extern u8 BattleScript_BerryCureFrzEnd2[];
-extern u8 BattleScript_BerryCureSlpEnd2[];
-extern u8 BattleScript_BerryCureConfusionEnd2[];
-extern u8 BattleScript_BerryCureChosenStatusEnd2[]; //berry cure any status end2
-extern u8 BattleScript_BerryCureParRet[];
-extern u8 BattleScript_BerryCurePsnRet[];
-extern u8 BattleScript_BerryCureBrnRet[];
-extern u8 BattleScript_BerryCureFrzRet[];
-extern u8 BattleScript_BerryCureSlpRet[];
-extern u8 BattleScript_BerryCureConfusionRet[];
-extern u8 BattleScript_BerryCureChosenStatusRet[]; //berry cure any status return
-
-extern u8 BattleScript_ItemHealHP_Ret[];
-
-extern u8 gUnknown_081D995F[]; //disobedient while asleep
-extern u8 BattleScript_IgnoresAndUsesRandomMove[]; //disobedient, uses a random move
-extern u8 BattleScript_IgnoresAndFallsAsleep[]; //disobedient, went to sleep
-extern u8 gUnknown_081D99A0[]; //disobedient, hits itself
-
-//array entries for battle communication
-#define MOVE_EFFECT_BYTE 0x3
-#define MULTISTRING_CHOOSER 0x5
-#define MSG_DISPLAY 0x7
-
-u8 GetBattleBank(u8 caseId)
-{
- u8 ret = 0;
- switch (caseId)
- {
- case BS_GET_TARGET:
- ret = gBankTarget;
- break;
- case BS_GET_ATTACKER:
- ret = gBankAttacker;
- break;
- case BS_GET_EFFECT_BANK:
- ret = gEffectBank;
- break;
- case BS_GET_BANK_0:
- ret = 0;
- break;
- case BS_GET_SCRIPTING_BANK:
- ret = ewram16003;
- break;
- case BS_GET_gBank1:
- ret = gBank1;
- break;
- case 5:
- ret = gBank1;
- break;
- }
- return ret;
-}
-
-void PressurePPLose(u8 bankDef, u8 bankAtk, u16 move)
-{
- s32 i;
-
- if (gBattleMons[bankDef].ability != ABILITY_PRESSURE)
- return;
-
- for (i = 0; i < 4; i++)
- {
- if (gBattleMons[bankAtk].moves[i] == move)
- break;
- }
-
- if (i == 4) // mons don't share any moves
- return;
-
- if (gBattleMons[bankAtk].pp[i] != 0)
- gBattleMons[bankAtk].pp[i]--;
-
- if (!(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED)
- && !(gDisableStructs[bankAtk].unk18_b & gBitTable[i]))
- {
- gActiveBattler = bankAtk;
- EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBattler].pp[i]);
- MarkBufferBankForExecution(gActiveBattler);
- }
-}
-
-void PressurePPLoseOnUsingImprision(u8 bankAtk)
-{
- s32 i, j;
- s32 imprisionPos = 4;
- u8 atkSide = GetBattlerSide(bankAtk);
-
- for (i = 0; i < gBattlersCount; i++)
- {
- if (atkSide != GetBattlerSide(i) && gBattleMons[i].ability == ABILITY_PRESSURE)
- {
- for (j = 0; j < 4; j++)
- {
- if (gBattleMons[bankAtk].moves[j] == MOVE_IMPRISON)
- break;
- }
- if (j != 4)
- {
- imprisionPos = j;
- if (gBattleMons[bankAtk].pp[j] != 0)
- gBattleMons[bankAtk].pp[j]--;
- }
- }
- }
-
- if (imprisionPos != 4
- && !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED)
- && !(gDisableStructs[bankAtk].unk18_b & gBitTable[imprisionPos]))
- {
- gActiveBattler = bankAtk;
- EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + imprisionPos, 0, 1, &gBattleMons[gActiveBattler].pp[imprisionPos]);
- MarkBufferBankForExecution(gActiveBattler);
- }
-}
-
-void PressurePPLoseOnUsingPerishSong(u8 bankAtk)
-{
- s32 i, j;
- s32 perishSongPos = 4;
-
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ABILITY_PRESSURE && i != bankAtk)
- {
- for (j = 0; j < 4; j++)
- {
- if (gBattleMons[bankAtk].moves[j] == MOVE_PERISH_SONG)
- break;
- }
- if (j != 4)
- {
- perishSongPos = j;
- if (gBattleMons[bankAtk].pp[j] != 0)
- gBattleMons[bankAtk].pp[j]--;
- }
- }
- }
-
- if (perishSongPos != 4
- && !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED)
- && !(gDisableStructs[bankAtk].unk18_b & gBitTable[perishSongPos]))
- {
- gActiveBattler = bankAtk;
- EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + perishSongPos, 0, 1, &gBattleMons[gActiveBattler].pp[perishSongPos]);
- MarkBufferBankForExecution(gActiveBattler);
- }
-}
-
-
-void MarkAllBufferBanksForExecution(void) // unused
-{
- s32 i;
-
- if (gBattleTypeFlags & BATTLE_TYPE_LINK)
- {
- for (i = 0; i < gBattlersCount; i++)
- gBattleExecBuffer |= gBitTable[i] << 0x1C;
- }
- else
- {
- for (i = 0; i < gBattlersCount; i++)
- gBattleExecBuffer |= gBitTable[i];
- }
-}
-
-void MarkBufferBankForExecution(u8 bank)
-{
- if (gBattleTypeFlags & BATTLE_TYPE_LINK)
- {
- gBattleExecBuffer |= gBitTable[bank] << 0x1C;
- }
- else
- {
- gBattleExecBuffer |= gBitTable[bank];
- }
-}
-
-void sub_80155A4(u8 arg0)
-{
- s32 i;
-
- for (i = 0; i < GetLinkPlayerCount(); i++)
- gBattleExecBuffer |= gBitTable[arg0] << (i << 2);
-
- gBattleExecBuffer &= ~(0x10000000 << arg0);
-}
-
-void CancelMultiTurnMoves(u8 bank)
-{
- gBattleMons[bank].status2 &= ~(STATUS2_MULTIPLETURNS);
- gBattleMons[bank].status2 &= ~(STATUS2_LOCK_CONFUSE);
- gBattleMons[bank].status2 &= ~(STATUS2_UPROAR);
- gBattleMons[bank].status2 &= ~(STATUS2_BIDE);
-
- gStatuses3[bank] &= ~(STATUS3_SEMI_INVULNERABLE);
-
- gDisableStructs[bank].rolloutTimer1 = 0;
- gDisableStructs[bank].furyCutterCounter = 0;
-}
-
-bool8 WasUnableToUseMove(u8 bank)
-{
- if (gProtectStructs[bank].prlzImmobility
- || gProtectStructs[bank].notEffective
- || gProtectStructs[bank].usedImprisionedMove
- || gProtectStructs[bank].loveImmobility
- || gProtectStructs[bank].usedDisabledMove
- || gProtectStructs[bank].usedTauntedMove
- || gProtectStructs[bank].flag2Unknown
- || gProtectStructs[bank].flinchImmobility
- || gProtectStructs[bank].confusionSelfDmg)
- return TRUE;
- else
- return FALSE;
-}
-
-void PrepareStringBattle(u16 stringId, u8 bank)
-{
- gActiveBattler = bank;
- EmitPrintString(0, stringId);
- MarkBufferBankForExecution(gActiveBattler);
-}
-
-void ResetSentPokesToOpponentValue(void)
-{
- s32 i;
- u32 bits = 0;
-
- gSentPokesToOpponent[0] = 0;
- gSentPokesToOpponent[1] = 0;
-
- for (i = 0; i < gBattlersCount; i += 2)
- bits |= gBitTable[gBattlerPartyIndexes[i]];
-
- for (i = 1; i < gBattlersCount; i += 2)
- gSentPokesToOpponent[(i & BIT_FLANK) >> 1] = bits;
-}
-
-void sub_8015740(u8 bank)
-{
- s32 i = 0;
- u32 bits = 0;
-
- if (GetBattlerSide(bank) == B_SIDE_OPPONENT)
- {
- u8 id = ((bank & BIT_FLANK) >> 1);
- gSentPokesToOpponent[id] = 0;
-
- for (i = 0; i < gBattlersCount; i += 2)
- {
- if (!(gAbsentBattlerFlags & gBitTable[i]))
- bits |= gBitTable[gBattlerPartyIndexes[i]];
- }
-
- gSentPokesToOpponent[id] = bits;
- }
-}
-
-void sub_80157C4(u8 bank)
-{
- if (GetBattlerSide(bank) == B_SIDE_OPPONENT)
- {
- sub_8015740(bank);
- }
- else
- {
- s32 i;
- for (i = 1; i < gBattlersCount; i++)
- gSentPokesToOpponent[(i & BIT_FLANK) >> 1] |= gBitTable[gBattlerPartyIndexes[bank]];
- }
-}
-
-void BattleScriptPush(const u8* BS_ptr)
-{
- B_BATTLESCRIPTS_STACK->ptr[B_BATTLESCRIPTS_STACK->size++] = BS_ptr;
-}
-
-void BattleScriptPushCursor(void)
-{
- B_BATTLESCRIPTS_STACK->ptr[B_BATTLESCRIPTS_STACK->size++] = gBattlescriptCurrInstr;
-}
-
-void BattleScriptPop(void)
-{
- gBattlescriptCurrInstr = B_BATTLESCRIPTS_STACK->ptr[--B_BATTLESCRIPTS_STACK->size];
-}
-
-u8 TrySetCantSelectMoveBattleScript(void) //msg can't select a move
-{
- u8 limitations = 0;
- u16 move = gBattleMons[gActiveBattler].moves[gBattleBufferB[gActiveBattler][2]];
- u8 holdEffect;
- u16* choicedMove = CHOICED_MOVE(gActiveBattler);
- if (gDisableStructs[gActiveBattler].disabledMove == move && move)
- {
- gBattleStruct->scriptingActive = gActiveBattler;
- gCurrentMove = move;
- gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionDisabledMove;
- limitations++;
- }
- if (move == gLastUsedMove[gActiveBattler] && move != MOVE_STRUGGLE && gBattleMons[gActiveBattler].status2 & STATUS2_TORMENT)
- {
- CancelMultiTurnMoves(gActiveBattler);
- gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionTormented;
- limitations++;
- }
- if (gDisableStructs[gActiveBattler].tauntTimer1 && gBattleMoves[move].power == 0)
- {
- gCurrentMove = move;
- gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionTaunted;
- limitations++;
- }
- if (IsImprisoned(gActiveBattler, move))
- {
- gCurrentMove = move;
- gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionImprisoned;
- limitations++;
- }
- if (gBattleMons[gActiveBattler].item == ITEM_ENIGMA_BERRY)
- holdEffect = gEnigmaBerries[gActiveBattler].holdEffect;
- else
- holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item);
- gStringBank = gActiveBattler;
- if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move)
- {
- gCurrentMove = *choicedMove;
- gLastUsedItem = gBattleMons[gActiveBattler].item;
- gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionChoiceBanded;
- limitations++;
- }
- if (gBattleMons[gActiveBattler].pp[gBattleBufferB[gActiveBattler][2]] == 0)
- {
- gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionNoPP;
- limitations++;
- }
- return limitations;
-}
-
-#define MOVE_LIMITATION_ZEROMOVE (1 << 0)
-#define MOVE_LIMITATION_PP (1 << 1)
-#define MOVE_LIMITATION_DISABLED (1 << 2)
-#define MOVE_LIMITATION_TORMENTED (1 << 3)
-#define MOVE_LIMITATION_TAUNT (1 << 4)
-#define MOVE_LIMITATION_IMPRISION (1 << 5)
-
-u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check)
-{
- u8 holdEffect;
- u16* choicedMove = CHOICED_MOVE(bank);
- s32 i;
- if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY)
- holdEffect = gEnigmaBerries[bank].holdEffect;
- else
- holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item);
- gStringBank = bank;
- for (i = 0; i < 4; i++)
- {
- if (gBattleMons[bank].moves[i] == 0 && check & MOVE_LIMITATION_ZEROMOVE)
- unusableMoves |= gBitTable[i];
- if (gBattleMons[bank].pp[i] == 0 && check & MOVE_LIMITATION_PP)
- unusableMoves |= gBitTable[i];
- if (gBattleMons[bank].moves[i] == gDisableStructs[bank].disabledMove && check & MOVE_LIMITATION_DISABLED)
- unusableMoves |= gBitTable[i];
- if (gBattleMons[bank].moves[i] == gLastUsedMove[bank] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[bank].status2 & STATUS2_TORMENT)
- unusableMoves |= gBitTable[i];
- if (gDisableStructs[bank].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[bank].moves[i]].power == 0)
- unusableMoves |= gBitTable[i];
- if (IsImprisoned(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION)
- unusableMoves |= gBitTable[i];
- if (gDisableStructs[bank].encoreTimer1 && gDisableStructs[bank].encoredMove != gBattleMons[bank].moves[i])
- unusableMoves |= gBitTable[i];
- if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[bank].moves[i])
- unusableMoves |= gBitTable[i];
- }
- return unusableMoves;
-}
-
-bool8 AreAllMovesUnusable(void)
-{
- u8 unusable;
- unusable = CheckMoveLimitations(gActiveBattler, 0, 0xFF);
- if (unusable == 0xF) //all moves are unusable
- {
- gProtectStructs[gActiveBattler].onlyStruggle = 1;
- gSelectionBattleScripts[gActiveBattler] = BattleScript_NoMovesLeft;
- if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- gBattleBufferB[gActiveBattler][3] = GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) ^ 1) | (Random() & 2));
- else
- gBattleBufferB[gActiveBattler][3] = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ 1);
- }
- else
- gProtectStructs[gActiveBattler].onlyStruggle = 0;
- return (unusable == 0xF);
-}
-
-u8 IsImprisoned(u8 bank, u16 move)
-{
- u8 imprisionedMoves = 0;
- u8 bankSide = GetBattlerSide(bank);
- s32 i;
- for (i = 0; i < gBattlersCount; i++)
- {
- if (bankSide != GetBattlerSide(i) && gStatuses3[i] & STATUS3_IMPRISIONED)
- {
- s32 j;
- for (j = 0; j < 4; j++)
- {
- if (move == gBattleMons[i].moves[j])
- break;
- }
- if (j < 4)
- imprisionedMoves++;
- }
- }
- return imprisionedMoves;
-}
-
-u8 UpdateTurnCounters(void)
-{
- u8 effect = 0;
- s32 i;
-
- for (gBankAttacker = 0; gBankAttacker < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBankAttacker]; gBankAttacker++)
- {
- }
- for (gBankTarget = 0; gBankTarget < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBankTarget]; gBankTarget++)
- {
- }
-
- do
- {
- u8 sideBank;
-
- switch (gBattleStruct->turncountersTracker)
- {
- case 0:
- for (i = 0; i < gBattlersCount; i++)
- {
- gBanksByTurnOrder[i] = i;
- }
- for (i = 0; i < gBattlersCount - 1; i++)
- {
- s32 j;
- for (j = i + 1; j < gBattlersCount; j++)
- {
- if (GetWhoStrikesFirst(gBanksByTurnOrder[i], gBanksByTurnOrder[j], 0))
- SwapTurnOrder(i, j);
- }
- }
- gBattleStruct->turncountersTracker++;
- gBattleStruct->turnSideTracker = 0;
- case 1:
- while (gBattleStruct->turnSideTracker < 2)
- {
- gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker;
-
- if (gSideAffecting[sideBank] & SIDE_STATUS_REFLECT)
- {
- if (--gSideTimers[sideBank].reflectTimer == 0)
- {
-
- gSideAffecting[sideBank] &= ~SIDE_STATUS_REFLECT;
- BattleScriptExecute(BattleScript_SideStatusWoreOff);
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 2;
- gBattleTextBuff1[2] = MOVE_REFLECT;
- gBattleTextBuff1[3] = MOVE_REFLECT >> 8;
- gBattleTextBuff1[4] = EOS;
- effect++;
- }
- }
- gBattleStruct->turnSideTracker++;
- if (effect)
- break;
- }
- if (!effect)
- {
- gBattleStruct->turncountersTracker++;
- gBattleStruct->turnSideTracker = 0;
- }
- break;
- case 2:
- while (gBattleStruct->turnSideTracker < 2)
- {
- gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker;
- if (gSideAffecting[sideBank] & SIDE_STATUS_LIGHTSCREEN)
- {
- if (--gSideTimers[sideBank].lightscreenTimer == 0)
- {
- gSideAffecting[sideBank] &= ~SIDE_STATUS_LIGHTSCREEN;
- BattleScriptExecute(BattleScript_SideStatusWoreOff);
- gBattleCommunication[MULTISTRING_CHOOSER] = sideBank;
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 2;
- gBattleTextBuff1[2] = MOVE_LIGHT_SCREEN;
- gBattleTextBuff1[3] = MOVE_LIGHT_SCREEN >> 8;
- gBattleTextBuff1[4] = EOS;
- effect++;
- }
- }
- gBattleStruct->turnSideTracker++;
- if (effect)
- break;
- }
- if (!effect)
- {
- gBattleStruct->turncountersTracker++;
- gBattleStruct->turnSideTracker = 0;
- }
- break;
- case 3:
- while (gBattleStruct->turnSideTracker < 2)
- {
- gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker;
- if (gSideTimers[sideBank].mistTimer && --gSideTimers[sideBank].mistTimer == 0)
- {
- gSideAffecting[sideBank] &= ~SIDE_STATUS_MIST;
- BattleScriptExecute(BattleScript_SideStatusWoreOff);
- gBattleCommunication[MULTISTRING_CHOOSER] = sideBank;
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 2;
- gBattleTextBuff1[2] = MOVE_MIST;
- gBattleTextBuff1[3] = MOVE_MIST >> 8;
- gBattleTextBuff1[4] = EOS;
- effect++;
- }
- gBattleStruct->turnSideTracker++;
- if (effect)
- break;
- }
- if (!effect)
- {
- gBattleStruct->turncountersTracker++;
- gBattleStruct->turnSideTracker = 0;
- }
- break;
- case 4:
- while (gBattleStruct->turnSideTracker < 2)
- {
- gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker;
- if (gSideAffecting[sideBank] & SIDE_STATUS_SAFEGUARD)
- {
- if (--gSideTimers[sideBank].safeguardTimer == 0)
- {
- gSideAffecting[sideBank] &= ~SIDE_STATUS_SAFEGUARD;
- BattleScriptExecute(BattleScript_SafeguardEnds);
- effect++;
- }
- }
- gBattleStruct->turnSideTracker++;
- if (effect)
- break;
- }
- if (!effect)
- {
- gBattleStruct->turncountersTracker++;
- gBattleStruct->turnSideTracker = 0;
- }
- break;
- case 5:
- while (gBattleStruct->turnSideTracker < gBattlersCount)
- {
- gActiveBattler = gBanksByTurnOrder[gBattleStruct->turnSideTracker];
- if (gWishFutureKnock.wishCounter[gActiveBattler] && --gWishFutureKnock.wishCounter[gActiveBattler] == 0 && gBattleMons[gActiveBattler].hp)
- {
- gBankTarget = gActiveBattler;
- BattleScriptExecute(BattleScript_WishComesTrue);
- effect++;
- }
- gBattleStruct->turnSideTracker++;
- if (effect)
- break;
- }
- if (!effect)
- {
- gBattleStruct->turncountersTracker++;
- }
- break;
- case 6:
- if (gBattleWeather & WEATHER_RAIN_ANY)
- {
- if (!(gBattleWeather & WEATHER_RAIN_PERMANENT))
- {
- if (--gWishFutureKnock.weatherDuration == 0)
- {
- gBattleWeather &= ~WEATHER_RAIN_TEMPORARY;
- gBattleWeather &= ~WEATHER_RAIN_DOWNPOUR;
- gBattleCommunication[MULTISTRING_CHOOSER] = 2;
- }
- else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR)
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- else
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- }
- else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR)
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- else
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- BattleScriptExecute(BattleScript_RainContinuesOrEnds);
- effect++;
- }
- gBattleStruct->turncountersTracker++;
- break;
- case 7:
- if (gBattleWeather & WEATHER_SANDSTORM_ANY)
- {
- if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
- {
- gBattleWeather &= ~WEATHER_SANDSTORM_TEMPORARY;
- gBattlescriptCurrInstr = BattleScript_SandStormHailEnds;
- }
- else
- gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues;
-
- gBattleStruct->animArg1 = B_ANIM_SANDSTORM_CONTINUES;
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- BattleScriptExecute(gBattlescriptCurrInstr);
- effect++;
- }
- gBattleStruct->turncountersTracker++;
- break;
- case 8:
- if (gBattleWeather & WEATHER_SUN_ANY)
- {
- if (!(gBattleWeather & WEATHER_SUN_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
- {
- gBattleWeather &= ~WEATHER_SUN_TEMPORARY;
- gBattlescriptCurrInstr = BattleScript_SunlightFaded;
- }
- else
- gBattlescriptCurrInstr = BattleScript_SunlightContinues;
-
- BattleScriptExecute(gBattlescriptCurrInstr);
- effect++;
- }
- gBattleStruct->turncountersTracker++;
- break;
- case 9:
- if (gBattleWeather & WEATHER_HAIL)
- {
- if (--gWishFutureKnock.weatherDuration == 0)
- {
- gBattleWeather &= ~WEATHER_HAIL;
- gBattlescriptCurrInstr = BattleScript_SandStormHailEnds;
- }
- else
- gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues;
-
- gBattleStruct->animArg1 = B_ANIM_HAIL_CONTINUES;
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- BattleScriptExecute(gBattlescriptCurrInstr);
- effect++;
- }
- gBattleStruct->turncountersTracker++;
- break;
- case 10:
- effect++;
- break;
- }
- } while (effect == 0);
- return (gBattleMainFunc != BattleTurnPassed);
-}
-
-#define TURNBASED_MAX_CASE 19
-
-u8 TurnBasedEffects(void)
-{
- u8 effect = 0;
-
- gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20);
- while (gBattleStruct->turnEffectsBank < gBattlersCount && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE)
- {
- gActiveBattler = gBankAttacker = gBanksByTurnOrder[gBattleStruct->turnEffectsBank];
- if (gAbsentBattlerFlags & gBitTable[gActiveBattler])
- {
- gBattleStruct->turnEffectsBank++;
- }
- else
- {
- switch (gBattleStruct->turnEffectsTracker)
- {
- case 0: // ingrain
- if ((gStatuses3[gActiveBattler] & STATUS3_ROOTED)
- && gBattleMons[gActiveBattler].hp != gBattleMons[gActiveBattler].maxHP
- && gBattleMons[gActiveBattler].hp != 0)
- {
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
- BattleScriptExecute(BattleScript_IngrainTurnHeal);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 1: // end turn abilities
- if (AbilityBattleEffects(ABILITYEFFECT_ENDTURN, gActiveBattler, 0, 0, 0))
- effect++;
- gBattleStruct->turnEffectsTracker++;
- break;
- case 2: // item effects
- if (ItemBattleEffects(1, gActiveBattler, 0))
- effect++;
- gBattleStruct->turnEffectsTracker++;
- break;
- case 18: // item effects again
- if (ItemBattleEffects(1, gActiveBattler, 1))
- effect++;
- gBattleStruct->turnEffectsTracker++;
- break;
- case 3: // leech seed
- if (gStatuses3[gActiveBattler] & STATUS3_LEECHSEED && gBattleMons[gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK].hp != 0 && gBattleMons[gActiveBattler].hp != 0)
- {
- gBankTarget = gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the bank that receives HP
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleStruct->animArg1 = gBankTarget;
- gBattleStruct->animArg2 = gBankAttacker;
- BattleScriptExecute(BattleScript_LeechSeedTurnDrain);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 4: // poison
- if ((gBattleMons[gActiveBattler].status1 & STATUS_POISON) && gBattleMons[gActiveBattler].hp != 0)
- {
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- BattleScriptExecute(BattleScript_PoisonTurnDmg);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 5: // toxic poison
- if ((gBattleMons[gActiveBattler].status1 & STATUS_TOXIC_POISON) && gBattleMons[gActiveBattler].hp != 0)
- {
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- if ((gBattleMons[gActiveBattler].status1 & 0xF00) != 0xF00) //not 16 turns
- gBattleMons[gActiveBattler].status1 += 0x100;
- gBattleMoveDamage *= (gBattleMons[gActiveBattler].status1 & 0xF00) >> 8;
- BattleScriptExecute(BattleScript_PoisonTurnDmg);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 6: // burn
- if ((gBattleMons[gActiveBattler].status1 & STATUS_BURN) && gBattleMons[gActiveBattler].hp != 0)
- {
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- BattleScriptExecute(BattleScript_BurnTurnDmg);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 7: // spooky nightmares
- if ((gBattleMons[gActiveBattler].status2 & STATUS2_NIGHTMARE) && gBattleMons[gActiveBattler].hp != 0)
- {
- // missing sleep check
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- BattleScriptExecute(BattleScript_NightmareTurnDmg);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 8: // curse
- if ((gBattleMons[gActiveBattler].status2 & STATUS2_CURSED) && gBattleMons[gActiveBattler].hp != 0)
- {
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- BattleScriptExecute(BattleScript_CurseTurnDmg);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 9: // wrap
- if ((gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBattler].hp != 0)
- {
- gBattleMons[gActiveBattler].status2 -= 0x2000;
- if (gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) // damaged by wrap
- {
- gBattleStruct->animArg1 = ewram16004arr(0, gActiveBattler);
- gBattleStruct->animArg2 = ewram16004arr(1, gActiveBattler);
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 2;
- gBattleTextBuff1[2] = ewram16004arr(0, gActiveBattler);
- gBattleTextBuff1[3] = ewram16004arr(1, gActiveBattler);
- gBattleTextBuff1[4] = EOS;
- gBattlescriptCurrInstr = BattleScript_WrapTurnDmg;
- gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- }
- else // broke free
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 2;
- gBattleTextBuff1[2] = ewram16004arr(0, gActiveBattler);
- gBattleTextBuff1[3] = ewram16004arr(1, gActiveBattler);
- gBattleTextBuff1[4] = EOS;
- gBattlescriptCurrInstr = BattleScript_WrapEnds;
- }
- BattleScriptExecute(gBattlescriptCurrInstr);
- effect++;
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 10: // uproar
- if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR)
- {
- for (gBankAttacker = 0; gBankAttacker < gBattlersCount; gBankAttacker++)
- {
- if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP)
- && gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF)
- {
- gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP);
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE);
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- BattleScriptExecute(BattleScript_MonWokeUpInUproar);
- gActiveBattler = gBankAttacker;
- EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
- MarkBufferBankForExecution(gActiveBattler);
- break;
- }
- }
- if (gBankAttacker != gBattlersCount)
- {
- effect = 2; // a pokemon was awaken
- break;
- }
- else
- {
- gBankAttacker = gActiveBattler;
- gBattleMons[gActiveBattler].status2 -= 0x10; // uproar timer goes down
- if (WasUnableToUseMove(gActiveBattler))
- {
- CancelMultiTurnMoves(gActiveBattler);
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- }
- else if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR)
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- gBattleMons[gActiveBattler].status2 |= STATUS2_MULTIPLETURNS;
- }
- else
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- CancelMultiTurnMoves(gActiveBattler);
- }
- BattleScriptExecute(BattleScript_PrintUproarOverTurns);
- effect = 1;
- }
- }
- if (effect != 2)
- gBattleStruct->turnEffectsTracker++;
- break;
- case 11: // thrash
- if (gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE)
- {
- gBattleMons[gActiveBattler].status2 -= 0x400;
- if (WasUnableToUseMove(gActiveBattler))
- CancelMultiTurnMoves(gActiveBattler);
- else if (!(gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE)
- && (gBattleMons[gActiveBattler].status2 & STATUS2_MULTIPLETURNS))
- {
- gBattleMons[gActiveBattler].status2 &= ~(STATUS2_MULTIPLETURNS);
- if (!(gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION))
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 0x47;
- SetMoveEffect(1, 0);
- if (gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION)
- BattleScriptExecute(BattleScript_ThrashConfuses);
- effect++;
- }
- }
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 12: // disable
- if (gDisableStructs[gActiveBattler].disableTimer1 != 0)
- {
- int i;
- for (i = 0; i < 4; i++)
- {
- if (gDisableStructs[gActiveBattler].disabledMove == gBattleMons[gActiveBattler].moves[i])
- break;
- }
- if (i == 4) // pokemon does not have the disabled move anymore
- {
- gDisableStructs[gActiveBattler].disabledMove = 0;
- gDisableStructs[gActiveBattler].disableTimer1 = 0;
- }
- else if (--gDisableStructs[gActiveBattler].disableTimer1 == 0) // disable ends
- {
- gDisableStructs[gActiveBattler].disabledMove = 0;
- BattleScriptExecute(BattleScript_DisabledNoMore);
- effect++;
- }
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 13: // encore
- if (gDisableStructs[gActiveBattler].encoreTimer1 != 0)
- {
- if (gBattleMons[gActiveBattler].moves[gDisableStructs[gActiveBattler].encoredMovePos] != gDisableStructs[gActiveBattler].encoredMove) // pokemon does not have the encored move anymore
- {
- gDisableStructs[gActiveBattler].encoredMove = 0;
- gDisableStructs[gActiveBattler].encoreTimer1 = 0;
- }
- else if (--gDisableStructs[gActiveBattler].encoreTimer1 == 0
- || gBattleMons[gActiveBattler].pp[gDisableStructs[gActiveBattler].encoredMovePos] == 0)
- {
- gDisableStructs[gActiveBattler].encoredMove = 0;
- gDisableStructs[gActiveBattler].encoreTimer1 = 0;
- BattleScriptExecute(BattleScript_EncoredNoMore);
- effect++;
- }
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 14: // lock-on decrement
- if (gStatuses3[gActiveBattler] & STATUS3_ALWAYS_HITS)
- gStatuses3[gActiveBattler] -= 0x8;
- gBattleStruct->turnEffectsTracker++;
- break;
- case 15: // charge
- if (gDisableStructs[gActiveBattler].chargeTimer1 && --gDisableStructs[gActiveBattler].chargeTimer1 == 0)
- gStatuses3[gActiveBattler] &= ~STATUS3_CHARGED_UP;
- gBattleStruct->turnEffectsTracker++;
- break;
- case 16: // taunt
- if (gDisableStructs[gActiveBattler].tauntTimer1)
- gDisableStructs[gActiveBattler].tauntTimer1--;
- gBattleStruct->turnEffectsTracker++;
- break;
- case 17: // yawn
- if (gStatuses3[gActiveBattler] & STATUS3_YAWN)
- {
- gStatuses3[gActiveBattler] -= 0x800;
- if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS_ANY)
- && gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT
- && gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler))
- {
- CancelMultiTurnMoves(gActiveBattler);
- gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2;
- EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
- MarkBufferBankForExecution(gActiveBattler);
- gEffectBank = gActiveBattler;
- BattleScriptExecute(BattleScript_YawnMakesAsleep);
- effect++;
- }
- }
- gBattleStruct->turnEffectsTracker++;
- break;
- case 19: // done
- gBattleStruct->turnEffectsTracker = 0;
- gBattleStruct->turnEffectsBank++;
- break;
- }
- if (effect != 0)
- return effect;
- }
- }
- gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20);
- return 0;
-}
-
-bool8 HandleWishPerishSongOnTurnEnd(void)
-{
- gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20);
- switch (gBattleStruct->sub80170DC_Tracker)
- {
- case 0: // future sight
- while (gBattleStruct->sub80170DC_Bank < gBattlersCount)
- {
- gActiveBattler = gBattleStruct->sub80170DC_Bank;
- if (gAbsentBattlerFlags & gBitTable[gActiveBattler])
- gBattleStruct->sub80170DC_Bank++;
- else
- {
- gBattleStruct->sub80170DC_Bank++;
- if (gWishFutureKnock.futureSightCounter[gActiveBattler] && --gWishFutureKnock.futureSightCounter[gActiveBattler] == 0 && gBattleMons[gActiveBattler].hp)
- {
- if (gWishFutureKnock.futureSightMove[gActiveBattler] == MOVE_FUTURE_SIGHT)
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- else //Doom Desire
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 2;
- gBattleTextBuff1[2] = gWishFutureKnock.futureSightMove[gActiveBattler];
- gBattleTextBuff1[3] = gWishFutureKnock.futureSightMove[gActiveBattler] >> 8;
- gBattleTextBuff1[4] = 0xFF;
- gBankTarget = gActiveBattler;
- gBankAttacker = gWishFutureKnock.futureSightAttacker[gActiveBattler];
- gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBattler];
- gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF;
- BattleScriptExecute(BattleScript_MonTookFutureAttack);
- return 1;
- }
- }
- }
- gBattleStruct->sub80170DC_Tracker = 1;
- gBattleStruct->sub80170DC_Bank = 0;
- case 1: // perish song
- while (gBattleStruct->sub80170DC_Bank < gBattlersCount)
- {
- gActiveBattler = gBankAttacker = gBanksByTurnOrder[gBattleStruct->sub80170DC_Bank];
- if (gAbsentBattlerFlags & gBitTable[gActiveBattler])
- gBattleStruct->sub80170DC_Bank++;
- else
- {
- gBattleStruct->sub80170DC_Bank++;
- if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 1;
- gBattleTextBuff1[2] = 1;
- gBattleTextBuff1[3] = 1;
- gBattleTextBuff1[4] = gDisableStructs[gActiveBattler].perishSongTimer1;
- gBattleTextBuff1[5] = 0xFF;
- if (gDisableStructs[gActiveBattler].perishSongTimer1 == 0)
- {
- gStatuses3[gActiveBattler] &= ~(STATUS3_PERISH_SONG);
- gBattleMoveDamage = gBattleMons[gActiveBattler].hp;
- gBattlescriptCurrInstr = BattleScript_PerishSongHits;
- }
- else
- {
- gDisableStructs[gActiveBattler].perishSongTimer1--;
- gBattlescriptCurrInstr = BattleScript_PerishSongTimerGoesDown;
- }
- BattleScriptExecute(gBattlescriptCurrInstr);
- return 1;
- }
- }
- }
- break;
- }
- gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20);
- return 0;
-}
-
-#define HandleFaintedMonActions_MAX_CASE 7
-
-bool8 HandleFaintedMonActions(void)
-{
- if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
- return 0;
- do
- {
- int i;
- switch (gBattleStruct->sub80173A4_Tracker)
- {
- case 0:
- gBattleStruct->unk1605A = 0;
- gBattleStruct->sub80173A4_Tracker++;
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gAbsentBattlerFlags & gBitTable[i] && !sub_8018018(i, 6, 6))
- gAbsentBattlerFlags &= ~(gBitTable[i]);
- }
- case 1:
- do
- {
- gBank1 = gBankTarget = gBattleStruct->unk1605A;
- if (gBattleMons[gBattleStruct->unk1605A].hp == 0 && !(gBattleStruct->unk16113 & gBitTable[gBattlerPartyIndexes[gBattleStruct->unk1605A]]) && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->unk1605A]))
- {
- BattleScriptExecute(BattleScript_GiveExp);
- gBattleStruct->sub80173A4_Tracker = 2;
- return 1;
- }
- } while (++gBattleStruct->unk1605A != gBattlersCount);
- gBattleStruct->sub80173A4_Tracker = 3;
- break;
- case 2:
- sub_8015740(gBank1);
- if (++gBattleStruct->unk1605A == gBattlersCount)
- gBattleStruct->sub80173A4_Tracker = 3;
- else
- gBattleStruct->sub80173A4_Tracker = 1;
- break;
- case 3:
- gBattleStruct->unk1605A = 0;
- gBattleStruct->sub80173A4_Tracker++;
- case 4:
- do
- {
- gBank1 = gBankTarget = gBattleStruct->unk1605A; //or should banks be switched?
- if (gBattleMons[gBattleStruct->unk1605A].hp == 0 && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->unk1605A]))
- {
- BattleScriptExecute(BattleScript_HandleFaintedMon);
- gBattleStruct->sub80173A4_Tracker = 5;
- return 1;
- }
- } while (++gBattleStruct->unk1605A != gBattlersCount);
- gBattleStruct->sub80173A4_Tracker = 6;
- break;
- case 5:
- if (++gBattleStruct->unk1605A == gBattlersCount)
- gBattleStruct->sub80173A4_Tracker = 6;
- else
- gBattleStruct->sub80173A4_Tracker = 4;
- break;
- case 6:
- if (AbilityBattleEffects(9, 0, 0, 0, 0) || AbilityBattleEffects(0xB, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(6, 0, 0, 0, 0))
- return 1;
- gBattleStruct->sub80173A4_Tracker++;
- break;
- case 7:
- break;
- }
- } while (gBattleStruct->sub80173A4_Tracker != HandleFaintedMonActions_MAX_CASE);
- return 0;
-}
-
-void TryClearRageStatuses(void)
-{
- int i;
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].status2 & STATUS2_RAGE && gChosenMovesByBanks[i] != MOVE_RAGE)
- gBattleMons[i].status2 &= ~(STATUS2_RAGE);
- }
-}
-
-#define ATKCANCELLER_MAX_CASE 14
-
-u8 AtkCanceller_UnableToUseMove(void)
-{
- u8 effect = 0;
- s32* bideDmg = &gBattleStruct->bideDmg;
- do
- {
- switch (gBattleStruct->atkCancellerTracker)
- {
- case 0: // flags clear
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_DESTINY_BOND);
- gStatuses3[gBankAttacker] &= ~(STATUS3_GRUDGE);
- gBattleStruct->atkCancellerTracker++;
- break;
- case 1: // check being asleep
- if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP)
- {
- if (UproarWakeUpCheck(gBankAttacker))
- {
- gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP);
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE);
- BattleScriptPushCursor();
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
- effect = 2;
- }
- else
- {
- u8 toSub;
- if (gBattleMons[gBankAttacker].ability == ABILITY_EARLY_BIRD)
- toSub = 2;
- else
- toSub = 1;
- if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) < toSub)
- gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP);
- else
- gBattleMons[gBankAttacker].status1 -= toSub;
- if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP)
- {
- if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK)
- {
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 2;
- }
- }
- else
- {
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE);
- BattleScriptPushCursor();
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
- effect = 2;
- }
- }
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 2: // check being frozen
- if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE)
- {
- if (Random() % 5)
- {
- if (gBattleMoves[gCurrentMove].effect != EFFECT_THAW_HIT) // unfreezing via a move effect happens in case 13
- {
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
- gHitMarker |= HITMARKER_NO_ATTACKSTRING;
- }
- else
- {
- gBattleStruct->atkCancellerTracker++;
- break;
- }
- }
- else // unfreeze
- {
- gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- }
- effect = 2;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 3: // truant
- if (gBattleMons[gBankAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBankAttacker].truantCounter)
- {
- CancelMultiTurnMoves(gBankAttacker);
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 4: // recharge
- if (gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE)
- {
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RECHARGE);
- gDisableStructs[gBankAttacker].rechargeCounter = 0;
- CancelMultiTurnMoves(gBankAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 5: // flinch
- if (gBattleMons[gBankAttacker].status2 & STATUS2_FLINCHED)
- {
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_FLINCHED);
- gProtectStructs[gBankAttacker].flinchImmobility = 1;
- CancelMultiTurnMoves(gBankAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 6: // disabled move
- if (gDisableStructs[gBankAttacker].disabledMove == gCurrentMove && gDisableStructs[gBankAttacker].disabledMove != 0)
- {
- gProtectStructs[gBankAttacker].usedDisabledMove = 1;
- gBattleStruct->scriptingActive = gBankAttacker;
- CancelMultiTurnMoves(gBankAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 7: // taunt
- if (gDisableStructs[gBankAttacker].tauntTimer1 && gBattleMoves[gCurrentMove].power == 0)
- {
- gProtectStructs[gBankAttacker].usedTauntedMove = 1;
- CancelMultiTurnMoves(gBankAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 8: // imprisoned
- if (IsImprisoned(gBankAttacker, gCurrentMove))
- {
- gProtectStructs[gBankAttacker].usedImprisionedMove = 1;
- CancelMultiTurnMoves(gBankAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 9: // confusion
- if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION)
- {
- gBattleMons[gBankAttacker].status2--;
- if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION)
- {
- if (Random() & 1)
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- BattleScriptPushCursor();
- }
- else // confusion dmg
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- gBankTarget = gBankAttacker;
- gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker);
- gProtectStructs[gBankAttacker].confusionSelfDmg = 1;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- }
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused;
- }
- else // snapped out of confusion
- {
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore;
- }
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 10: // paralysis
- if (gBattleMons[gBankAttacker].status1 & STATUS_PARALYSIS && (Random() % 4) == 0)
- {
- gProtectStructs[gBankAttacker].prlzImmobility = 1;
- CancelMultiTurnMoves(gBankAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 11: // infatuation
- if (gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION)
- {
- gBattleStruct->scriptingActive = CountTrailingZeroBits((gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) >> 0x10);
- if (Random() & 1)
- BattleScriptPushCursor();
- else
- {
- BattleScriptPush(BattleScript_MoveUsedIsParalyzedCantAttack);
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- gProtectStructs[gBankAttacker].loveImmobility = 1;
- CancelMultiTurnMoves(gBankAttacker);
- }
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 12: // bide
- if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE)
- {
- gBattleMons[gBankAttacker].status2 -= 0x100;
- if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE)
- gBattlescriptCurrInstr = BattleScript_BideStoringEnergy;
- else
- {
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS);
- if (gTakenDmg[gBankAttacker])
- {
- gCurrentMove = MOVE_BIDE;
- *bideDmg = gTakenDmg[gBankAttacker] * 2;
- gBankTarget = gTakenDmgBanks[gBankAttacker];
- if (gAbsentBattlerFlags & gBitTable[gBankTarget])
- gBankTarget = GetMoveTarget(MOVE_BIDE, 1);
- gBattlescriptCurrInstr = BattleScript_BideAttack;
- }
- else
- gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack;
- }
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 13: // move thawing
- if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE)
- {
- if (gBattleMoves[gCurrentMove].effect == EFFECT_THAW_HIT)
- {
- gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- }
- effect = 2;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case 14: // last case
- break;
- }
-
- } while (gBattleStruct->atkCancellerTracker != ATKCANCELLER_MAX_CASE && effect == 0);
-
- if (effect == 2)
- {
- gActiveBattler = gBankAttacker;
- EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
- MarkBufferBankForExecution(gActiveBattler);
- }
- return effect;
-}
-
-bool8 sub_8018018(u8 bank, u8 r1, u8 r2)
-{
- struct Pokemon* party;
- u8 r7;
- u8 r6;
- s32 i;
- if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
- return 0;
- if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
- {
- r7 = sub_803FC34(bank);
- if (GetBattlerSide(bank) == 0)
- party = gPlayerParty;
- else
- party = gEnemyParty;
- r6 = sub_803FBFC(r7);
- for (i = r6 * 3; i < r6 * 3 + 3; i++)
- {
- if (GetMonData(&party[i], MON_DATA_HP) && GetMonData(&party[i], MON_DATA_SPECIES2) && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG)
- break;
- }
- return (i == r6 * 3 + 3);
- }
- else
- {
- if (GetBattlerSide(bank) == 1)
- {
- r7 = GetBattlerAtPosition(1);
- r6 = GetBattlerAtPosition(3);
- party = gEnemyParty;
- }
- else
- {
- r7 = GetBattlerAtPosition(0);
- r6 = GetBattlerAtPosition(2);
- party = gPlayerParty;
- }
- if (r1 == 6)
- r1 = gBattlerPartyIndexes[r7];
- if (r2 == 6)
- r2 = gBattlerPartyIndexes[r6];
- for (i = 0; i < 6; i++)
- {
- if (GetMonData(&party[i], MON_DATA_HP) && GetMonData(&party[i], MON_DATA_SPECIES2) && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG && i != r1 && i != r2 && i != ewram16068arr(r7) && i != ewram16068arr(r6))
- break;
- }
- return (i == 6);
- }
-}
-
-enum
-{
- CASTFORM_NO_CHANGE, //0
- CASTFORM_TO_NORMAL, //1
- CASTFORM_TO_FIRE, //2
- CASTFORM_TO_WATER, //3
- CASTFORM_TO_ICE, //4
-};
-
-u8 CastformDataTypeChange(u8 bank)
-{
- u8 formChange = 0;
- if (gBattleMons[bank].species != SPECIES_CASTFORM || gBattleMons[bank].ability != ABILITY_FORECAST || gBattleMons[bank].hp == 0)
- return CASTFORM_NO_CHANGE;
- if (!WEATHER_HAS_EFFECT && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL)
- {
- gBattleMons[bank].type1 = TYPE_NORMAL;
- gBattleMons[bank].type2 = TYPE_NORMAL;
- return CASTFORM_TO_NORMAL;
- }
- if (!WEATHER_HAS_EFFECT)
- return CASTFORM_NO_CHANGE;
- if (!(gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL)) && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL)
- {
- gBattleMons[bank].type1 = TYPE_NORMAL;
- gBattleMons[bank].type2 = TYPE_NORMAL;
- formChange = CASTFORM_TO_NORMAL;
- }
- if (gBattleWeather & WEATHER_SUN_ANY && gBattleMons[bank].type1 != TYPE_FIRE && gBattleMons[bank].type2 != TYPE_FIRE)
- {
- gBattleMons[bank].type1 = TYPE_FIRE;
- gBattleMons[bank].type2 = TYPE_FIRE;
- formChange = CASTFORM_TO_FIRE;
- }
- if (gBattleWeather & WEATHER_RAIN_ANY && gBattleMons[bank].type1 != TYPE_WATER && gBattleMons[bank].type2 != TYPE_WATER)
- {
- gBattleMons[bank].type1 = TYPE_WATER;
- gBattleMons[bank].type2 = TYPE_WATER;
- formChange = CASTFORM_TO_WATER;
- }
- if (gBattleWeather & WEATHER_HAIL && gBattleMons[bank].type1 != TYPE_ICE && gBattleMons[bank].type2 != TYPE_ICE)
- {
- gBattleMons[bank].type1 = TYPE_ICE;
- gBattleMons[bank].type2 = TYPE_ICE;
- formChange = CASTFORM_TO_ICE;
- }
- return formChange;
-}
-
-u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg)
-{
- u8 effect = 0;
- struct Pokemon* pokeAtk;
- struct Pokemon* pokeDef;
- u16 speciesAtk;
- u16 speciesDef;
- u32 pidAtk;
- u32 pidDef;
-
- if (gBankAttacker >= gBattlersCount)
- gBankAttacker = bank;
- if (GetBattlerSide(gBankAttacker) == 0)
- pokeAtk = &gPlayerParty[gBattlerPartyIndexes[gBankAttacker]];
- else
- pokeAtk = &gEnemyParty[gBattlerPartyIndexes[gBankAttacker]];
-
- if (gBankTarget >= gBattlersCount)
- gBankTarget = bank;
- if (GetBattlerSide(gBankTarget) == 0)
- pokeDef = &gPlayerParty[gBattlerPartyIndexes[gBankTarget]];
- else
- pokeDef = &gEnemyParty[gBattlerPartyIndexes[gBankTarget]];
-
- speciesAtk = GetMonData(pokeAtk, MON_DATA_SPECIES);
- pidAtk = GetMonData(pokeAtk, MON_DATA_PERSONALITY);
-
- speciesDef = GetMonData(pokeDef, MON_DATA_SPECIES);
- pidDef = GetMonData(pokeDef, MON_DATA_PERSONALITY);
-
- if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) // why isn't that check done at the beginning?
- {
- u8 moveType;
- s32 i;
- u16 move;
- u8 side;
- u8 target1;
-
- if (special)
- gLastUsedAbility = special;
- else
- gLastUsedAbility = gBattleMons[bank].ability;
-
- if (moveArg)
- move = moveArg;
- else
- move = gCurrentMove;
-
- if (gBattleStruct->dynamicMoveType)
- moveType = gBattleStruct->dynamicMoveType & 0x3F;
- else
- moveType = gBattleMoves[move].type;
-
- switch (caseID)
- {
- case ABILITYEFFECT_ON_SWITCHIN: // 0
- if (gBankAttacker >= gBattlersCount)
- gBankAttacker = bank;
- switch (gLastUsedAbility)
- {
- case 0xFF: //weather from overworld
- switch (GetCurrentWeather())
- {
- case WEATHER_RAIN_LIGHT:
- case WEATHER_RAIN_MED:
- case WEATHER_RAIN_HEAVY:
- if (!(gBattleWeather & WEATHER_RAIN_ANY))
- {
- gBattleWeather = (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_PERMANENT);
- gBattleStruct->animArg1 = B_ANIM_RAIN_CONTINUES;
- gBattleStruct->scriptingActive = bank;
- effect++;
- }
- break;
- case WEATHER_SANDSTORM:
- if (!(gBattleWeather & WEATHER_SANDSTORM_ANY))
- {
- gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY);
- gBattleStruct->animArg1 = B_ANIM_SANDSTORM_CONTINUES;
- gBattleStruct->scriptingActive = bank;
- effect++;
- }
- break;
- case WEATHER_DROUGHT:
- if (!(gBattleWeather & WEATHER_SUN_ANY))
- {
- gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY);
- gBattleStruct->animArg1 = B_ANIM_SUN_CONTINUES;
- gBattleStruct->scriptingActive = bank;
- effect++;
- }
- break;
- }
- if (effect)
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = GetCurrentWeather();
- BattleScriptPushCursorAndCallback(BattleScript_OverworldWeatherStarts);
- }
- break;
- case ABILITY_DRIZZLE:
- if (!(gBattleWeather & WEATHER_RAIN_PERMANENT))
- {
- gBattleWeather = (WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY);
- BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
- gBattleStruct->scriptingActive = bank;
- effect++;
- }
- break;
- case ABILITY_SAND_STREAM:
- if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT))
- {
- gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY);
- BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates);
- gBattleStruct->scriptingActive = bank;
- effect++;
- }
- break;
- case ABILITY_DROUGHT:
- if (!(gBattleWeather & WEATHER_SUN_PERMANENT))
- {
- gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY);
- BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
- gBattleStruct->scriptingActive = bank;
- effect++;
- }
- break;
- case ABILITY_INTIMIDATE:
- if (!(gSpecialStatuses[bank].intimidatedPoke))
- {
- gStatuses3[bank] |= STATUS3_INTIMIDATE_POKES;
- gSpecialStatuses[bank].intimidatedPoke = 1;
- }
- break;
- case ABILITY_FORECAST:
- effect = CastformDataTypeChange(bank);
- if (effect != 0)
- {
- BattleScriptPushCursorAndCallback(BattleScript_CastformChange);
- gBattleStruct->scriptingActive = bank;
- gBattleStruct->castformToChangeInto = effect - 1;
- }
- break;
- case ABILITY_TRACE:
- if (!(gSpecialStatuses[bank].traced))
- {
- gStatuses3[bank] |= STATUS3_TRACE;
- gSpecialStatuses[bank].traced = 1;
- }
- break;
- case ABILITY_CLOUD_NINE:
- case ABILITY_AIR_LOCK:
- {
- // that's a weird choice for a variable, why not use i or bank?
- for (target1 = 0; target1 < gBattlersCount; target1++)
- {
- effect = CastformDataTypeChange(target1);
- if (effect != 0)
- {
- BattleScriptPushCursorAndCallback(BattleScript_CastformChange);
- gBattleStruct->scriptingActive = target1;
- gBattleStruct->castformToChangeInto = effect - 1;
- break;
- }
- }
- }
- break;
- }
- break;
- case ABILITYEFFECT_ENDTURN: // 1
- if (gBattleMons[bank].hp != 0)
- {
- gBankAttacker = bank;
- switch (gLastUsedAbility)
- {
- case ABILITY_RAIN_DISH:
- if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY)
- && gBattleMons[bank].maxHP > gBattleMons[bank].hp)
- {
- gLastUsedAbility = ABILITY_RAIN_DISH; // why
- BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates);
- gBattleMoveDamage = gBattleMons[bank].maxHP / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
- effect++;
- }
- break;
- case ABILITY_SHED_SKIN:
- if ((gBattleMons[bank].status1 & STATUS_ANY) && (Random() % 3) == 0)
- {
- if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON))
- StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
- if (gBattleMons[bank].status1 & STATUS_SLEEP)
- StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
- if (gBattleMons[bank].status1 & STATUS_PARALYSIS)
- StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
- if (gBattleMons[bank].status1 & STATUS_BURN)
- StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
- if (gBattleMons[bank].status1 & STATUS_FREEZE)
- StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
- gBattleMons[bank].status1 = 0;
- // BUG: The nightmare status does not get cleared here. This was fixed in Emerald.
- //gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
- gBattleStruct->scriptingActive = gActiveBattler = bank;
- BattleScriptPushCursorAndCallback(BattleScript_ShedSkinActivates);
- EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1);
- MarkBufferBankForExecution(gActiveBattler);
- effect++;
- }
- break;
- case ABILITY_SPEED_BOOST:
- if (gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC && gDisableStructs[bank].isFirstTurn != 2)
- {
- gBattleMons[bank].statStages[STAT_STAGE_SPEED]++;
- gBattleStruct->animArg1 = 0x11;
- gBattleStruct->animArg2 = 0;
- BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates);
- gBattleStruct->scriptingActive = bank;
- effect++;
- }
- break;
- case ABILITY_TRUANT:
- gDisableStructs[gBankAttacker].truantCounter ^= 1;
- break;
- }
- }
- break;
- case ABILITYEFFECT_MOVES_BLOCK: // 2
- if (gLastUsedAbility == ABILITY_SOUNDPROOF)
- {
- for (i = 0; gSoundMovesTable[i] != 0xFFFF; i++)
- {
- if (gSoundMovesTable[i] == move)
- break;
- }
- if (gSoundMovesTable[i] != 0xFFFF)
- {
- if (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)
- gHitMarker |= HITMARKER_NO_PPDEDUCT;
- gBattlescriptCurrInstr = BattleScript_SoundproofProtected;
- effect = 1;
- }
- }
- break;
- case ABILITYEFFECT_ABSORBING: // 3
- if (move)
- {
- switch (gLastUsedAbility)
- {
- case ABILITY_VOLT_ABSORB:
- if (moveType == TYPE_ELECTRIC && gBattleMoves[move].power != 0)
- {
- if (gProtectStructs[gBankAttacker].notFirstStrike)
- gBattlescriptCurrInstr = BattleScript_MoveHPDrain;
- else
- gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss;
- effect = 1;
- }
- break;
- case ABILITY_WATER_ABSORB:
- if (moveType == TYPE_WATER && gBattleMoves[move].power != 0)
- {
- if (gProtectStructs[gBankAttacker].notFirstStrike)
- gBattlescriptCurrInstr = BattleScript_MoveHPDrain;
- else
- gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss;
- effect = 1;
- }
- break;
- case ABILITY_FLASH_FIRE:
- if (moveType == TYPE_FIRE && !(gBattleMons[bank].status1 & STATUS_FREEZE))
- {
- if (!(eFlashFireArr.arr[bank] & 1))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- if (gProtectStructs[gBankAttacker].notFirstStrike)
- gBattlescriptCurrInstr = BattleScript_FlashFireBoost;
- else
- gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss;
- eFlashFireArr.arr[bank] |= 1;
- effect = 2;
- }
- else
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- if (gProtectStructs[gBankAttacker].notFirstStrike)
- gBattlescriptCurrInstr = BattleScript_FlashFireBoost;
- else
- gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss;
- effect = 2;
- }
- }
- break;
- }
- if (effect == 1)
- {
- if (gBattleMons[bank].maxHP == gBattleMons[bank].hp)
- {
- if ((gProtectStructs[gBankAttacker].notFirstStrike))
- gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP;
- else
- gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP_PPLoss;
- }
- else
- {
- gBattleMoveDamage = gBattleMons[bank].maxHP / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
- }
- }
- }
- break;
- case ABILITYEFFECT_CONTACT: // 4
- switch (gLastUsedAbility)
- {
- case ABILITY_COLOR_CHANGE:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && move != MOVE_STRUGGLE
- && gBattleMoves[move].power != 0
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && gBattleMons[bank].type1 != moveType
- && gBattleMons[bank].type2 != moveType
- && gBattleMons[bank].hp != 0)
- {
- gBattleMons[bank].type1 = moveType;
- gBattleMons[bank].type2 = moveType;
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 3;
- gBattleTextBuff1[2] = moveType;
- gBattleTextBuff1[3] = 0xFF;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ColorChangeActivates;
- effect++;
- }
- break;
- case ABILITY_ROUGH_SKIN:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (gBattleMoves[move].flags & F_MAKES_CONTACT))
- {
- gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_RoughSkinActivates;
- effect++;
- }
- break;
- case ABILITY_EFFECT_SPORE:
- if (DEBUG && (gUnknown_02023A14_50 & 4))
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (gBattleMoves[move].flags & F_MAKES_CONTACT))
- {
- do
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3;
- } while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0);
- if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3)
- gBattleCommunication[MOVE_EFFECT_BYTE] += 2;
- gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- else
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (gBattleMoves[move].flags & F_MAKES_CONTACT)
- && (Random() % 10) == 0)
- {
- do
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3;
- } while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0);
- if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3)
- gBattleCommunication[MOVE_EFFECT_BYTE] += 2;
- gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- break;
- case ABILITY_POISON_POINT:
- if (DEBUG && (gUnknown_02023A14_50 & 4))
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (gBattleMoves[move].flags & F_MAKES_CONTACT))
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- else
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (gBattleMoves[move].flags & F_MAKES_CONTACT)
- && (Random() % 3) == 0)
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- break;
- case ABILITY_STATIC:
- if (DEBUG && (gUnknown_02023A14_50 & 4))
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (gBattleMoves[move].flags & F_MAKES_CONTACT))
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- else
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (gBattleMoves[move].flags & F_MAKES_CONTACT)
- && (Random() % 3) == 0)
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- break;
- case ABILITY_FLAME_BODY:
- if (DEBUG && (gUnknown_02023A14_50 & 4))
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gBattleMoves[move].flags & F_MAKES_CONTACT)
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- else
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gBattleMoves[move].flags & F_MAKES_CONTACT)
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (Random() % 3) == 0)
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- }
- break;
- case ABILITY_CUTE_CHARM:
- if (DEBUG && (gUnknown_02023A14_50 & 4))
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gBattleMoves[move].flags & F_MAKES_CONTACT)
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && gBattleMons[gBankTarget].hp != 0
- && gBattleMons[gBankAttacker].ability != ABILITY_OBLIVIOUS
- && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef)
- && !(gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION)
- && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != 0xFF
- && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF)
- {
- gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_CuteCharmActivates;
- effect++;
- }
- }
- else
- {
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBankAttacker].hp != 0
- && !gProtectStructs[gBankAttacker].confusionSelfDmg
- && (gBattleMoves[move].flags & F_MAKES_CONTACT)
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && gBattleMons[gBankTarget].hp != 0
- && (Random() % 3) == 0
- && gBattleMons[gBankAttacker].ability != ABILITY_OBLIVIOUS
- && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef)
- && !(gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION)
- && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != 0xFF
- && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF)
- {
- gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_CuteCharmActivates;
- effect++;
- }
- }
- break;
- }
- break;
- case ABILITYEFFECT_IMMUNITY: // 5
- {
- for (bank = 0; bank < gBattlersCount; bank++)
- {
- switch (gBattleMons[bank].ability)
- {
- case ABILITY_IMMUNITY:
- if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON | 0xF00)) // TODO: what is 0xF00?
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
- effect = 1;
- }
- break;
- case ABILITY_OWN_TEMPO:
- if (gBattleMons[bank].status2 & STATUS2_CONFUSION)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
- effect = 2;
- }
- break;
- case ABILITY_LIMBER:
- if (gBattleMons[bank].status1 & STATUS_PARALYSIS)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
- effect = 1;
- }
- break;
- case ABILITY_INSOMNIA:
- case ABILITY_VITAL_SPIRIT:
- if (gBattleMons[bank].status1 & STATUS_SLEEP)
- {
- gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
- StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
- effect = 1;
- }
- break;
- case ABILITY_WATER_VEIL:
- if (gBattleMons[bank].status1 & STATUS_BURN)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
- effect = 1;
- }
- break;
- case ABILITY_MAGMA_ARMOR:
- if (gBattleMons[bank].status1 & STATUS_FREEZE)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
- effect = 1;
- }
- break;
- case ABILITY_OBLIVIOUS:
- if (gBattleMons[bank].status2 & STATUS2_INFATUATION)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn);
- effect = 3;
- }
- break;
- }
- if (effect)
- {
- switch (effect)
- {
- case 1: // status cleared
- gBattleMons[bank].status1 = 0;
- break;
- case 2: // get rid of confusion
- gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION);
- break;
- case 3: // get rid of infatuation
- gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION);
- break;
- }
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus;
- gBattleStruct->scriptingActive = bank;
- gActiveBattler = bank;
- EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
- MarkBufferBankForExecution(gActiveBattler);
- return effect;
- }
- }
- }
- break;
- case ABILITYEFFECT_FORECAST: // 6
- {
- for (bank = 0; bank < gBattlersCount; bank++)
- {
- if (gBattleMons[bank].ability == ABILITY_FORECAST)
- {
- effect = CastformDataTypeChange(bank);
- if (effect)
- {
- BattleScriptPushCursorAndCallback(BattleScript_CastformChange);
- gBattleStruct->scriptingActive = bank;
- gBattleStruct->castformToChangeInto = effect - 1;
- return effect;
- }
- }
- }
- }
- break;
- case ABILITYEFFECT_SYNCHRONIZE: // 7
- if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT))
- {
- gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT);
- gBattleStruct->synchroniseEffect &= 0x3F;
- if (gBattleStruct->synchroniseEffect == 6)
- gBattleStruct->synchroniseEffect = 2;
- gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchroniseEffect + 0x40;
- gBattleStruct->scriptingActive = gBankTarget;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_SynchronizeActivates;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- break;
- case ABILITYEFFECT_ATK_SYNCHRONIZE: // 8
- if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT))
- {
- gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT);
- gBattleStruct->synchroniseEffect &= 0x3F;
- if (gBattleStruct->synchroniseEffect == 6)
- gBattleStruct->synchroniseEffect = 2;
- gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchroniseEffect;
- gBattleStruct->scriptingActive = gBankAttacker;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_SynchronizeActivates;
- gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
- effect++;
- }
- break;
- case ABILITYEFFECT_INTIMIDATE1: // 9
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gStatuses3[i] & STATUS3_INTIMIDATE_POKES)
- {
- gLastUsedAbility = ABILITY_INTIMIDATE;
- gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES);
- BattleScriptPushCursorAndCallback(gUnknown_081D978C);
- gBattleStruct->intimidateBank = i;
- effect++;
- break;
- }
- }
- break;
- case ABILITYEFFECT_TRACE: // 11
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ABILITY_TRACE && (gStatuses3[i] & STATUS3_TRACE))
- {
- u8 target2;
- side = (GetBattlerPosition(i) ^ 1) & 1;
- target1 = GetBattlerAtPosition(side);
- target2 = GetBattlerAtPosition(side + 2);
- if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- {
- if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0
- && gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0)
- {
- gActiveBattler = GetBattlerAtPosition(((Random() & 1) * 2) | side);
- gBattleMons[i].ability = gBattleMons[gActiveBattler].ability;
- gLastUsedAbility = gBattleMons[gActiveBattler].ability;
- effect++;
- }
- else if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0)
- {
- gActiveBattler = target1;
- gBattleMons[i].ability = gBattleMons[gActiveBattler].ability;
- gLastUsedAbility = gBattleMons[gActiveBattler].ability;
- effect++;
- }
- else if (gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0)
- {
- gActiveBattler = target2;
- gBattleMons[i].ability = gBattleMons[gActiveBattler].ability;
- gLastUsedAbility = gBattleMons[gActiveBattler].ability;
- effect++;
- }
- }
- else
- {
- gActiveBattler = target1;
- if (gBattleMons[target1].ability && gBattleMons[target1].hp)
- {
- gBattleMons[i].ability = gBattleMons[target1].ability;
- gLastUsedAbility = gBattleMons[target1].ability;
- effect++;
- }
- }
- if (effect)
- {
- BattleScriptPushCursorAndCallback(BattleScript_TraceActivates);
- gStatuses3[i] &= ~(STATUS3_TRACE);
- gBattleStruct->scriptingActive = i;
-
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 4;
- gBattleTextBuff1[2] = gActiveBattler;
- gBattleTextBuff1[3] = gBattlerPartyIndexes[gActiveBattler];
- gBattleTextBuff1[4] = EOS;
-
- gBattleTextBuff2[0] = 0xFD;
- gBattleTextBuff2[1] = 9;
- gBattleTextBuff2[2] = gLastUsedAbility;
- gBattleTextBuff2[3] = EOS;
- break;
- }
- }
- }
- break;
- case ABILITYEFFECT_INTIMIDATE2: // 10
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ABILITY_INTIMIDATE && (gStatuses3[i] & STATUS3_INTIMIDATE_POKES))
- {
- gLastUsedAbility = ABILITY_INTIMIDATE;
- gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = gUnknown_081D9795;
- gBattleStruct->intimidateBank = i;
- effect++;
- break;
- }
- }
- break;
- case ABILITYEFFECT_CHECK_OTHER_SIDE: // 12
- side = GetBattlerSide(bank);
- for (i = 0; i < gBattlersCount; i++)
- {
- if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability)
- {
- gLastUsedAbility = ability;
- effect = i + 1;
- }
- }
- break;
- case ABILITYEFFECT_CHECK_BANK_SIDE: // 13
- side = GetBattlerSide(bank);
- for (i = 0; i < gBattlersCount; i++)
- {
- if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability)
- {
- gLastUsedAbility = ability;
- effect = i + 1;
- }
- }
- break;
- case ABILITYEFFECT_FIELD_SPORT: // 14
- switch (gLastUsedAbility)
- {
- case 0xFD:
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gStatuses3[i] & STATUS3_MUDSPORT)
- effect = i + 1;
- }
- break;
- case 0xFE:
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gStatuses3[i] & STATUS3_WATERSPORT)
- effect = i + 1;
- }
- break;
- default:
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ability)
- {
- gLastUsedAbility = ability;
- effect = i + 1;
- }
- }
- break;
- }
- break;
- case ABILITYEFFECT_CHECK_ON_FIELD: // 19
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ability && gBattleMons[i].hp != 0)
- {
- gLastUsedAbility = ability;
- effect = i + 1;
- }
- }
- break;
- case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK: // 15
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ability && i != bank)
- {
- gLastUsedAbility = ability;
- effect = i + 1;
- }
- }
- break;
- case ABILITYEFFECT_COUNT_OTHER_SIZE: // 16
- side = GetBattlerSide(bank);
- for (i = 0; i < gBattlersCount; i++)
- {
- if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability)
- {
- gLastUsedAbility = ability;
- effect++;
- }
- }
- break;
- case ABILITYEFFECT_COUNT_BANK_SIDE: // 17
- side = GetBattlerSide(bank);
- for (i = 0; i < gBattlersCount; i++)
- {
- if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability)
- {
- gLastUsedAbility = ability;
- effect++;
- }
- }
- break;
- case ABILITYEFFECT_COUNT_ON_FIELD: // 18
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].ability == ability && i != bank)
- {
- gLastUsedAbility = ability;
- effect++;
- }
- }
- break;
- }
- if (effect && caseID < 0xC && gLastUsedAbility != 0xFF)
- RecordAbilityBattle(bank, gLastUsedAbility);
- }
-
- return effect;
-}
-
-void BattleScriptExecute(const u8* BS_ptr)
-{
- gBattlescriptCurrInstr = BS_ptr;
- B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size++] = gBattleMainFunc;
- gBattleMainFunc = RunBattleScriptCommands_PopCallbacksStack;
- gCurrentActionFuncId = 0;
-}
-
-void BattleScriptPushCursorAndCallback(u8* BS_ptr)
-{
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BS_ptr;
- B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size++] = gBattleMainFunc;
- gBattleMainFunc = RunBattleScriptCommands;
-}
-
-enum
-{
- ITEM_NO_EFFECT, // 0
- ITEM_STATUS_CHANGE, // 1
- ITEM_EFFECT_OTHER, // 2
- ITEM_PP_CHANGE, // 3
- ITEM_HP_CHANGE, // 4
- ITEM_STATS_CHANGE, // 5
-};
-
-enum
-{
- FLAVOR_SPICY, // 0
- FLAVOR_DRY, // 1
- FLAVOR_SWEET, // 2
- FLAVOR_BITTER, // 3
- FLAVOR_SOUR, // 4
-};
-
-u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn)
-{
- int i = 0;
- u8 effect = ITEM_NO_EFFECT;
- u8 changedPP = 0;
- u8 bankHoldEffect, atkHoldEffect, defHoldEffect;
- u8 bankQuality, atkQuality, defQuality;
- u16 atkItem, defItem;
-
- gLastUsedItem = gBattleMons[bank].item;
- if (gLastUsedItem == ITEM_ENIGMA_BERRY)
- {
- bankHoldEffect = gEnigmaBerries[bank].holdEffect;
- bankQuality = gEnigmaBerries[bank].holdEffectParam;
- }
- else
- {
- bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem);
- bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem);
- }
-
- atkItem = gBattleMons[gBankAttacker].item;
- if (atkItem == ITEM_ENIGMA_BERRY)
- {
- atkHoldEffect = gEnigmaBerries[gBankAttacker].holdEffect;
- atkQuality = gEnigmaBerries[gBankAttacker].holdEffectParam;
- }
- else
- {
- atkHoldEffect = ItemId_GetHoldEffect(atkItem);
- atkQuality = ItemId_GetHoldEffectParam(atkItem);
- }
-
- // def variables are unused
- defItem = gBattleMons[gBankTarget].item;
- if (defItem == ITEM_ENIGMA_BERRY)
- {
- defHoldEffect = gEnigmaBerries[gBankTarget].holdEffect;
- defQuality = gEnigmaBerries[gBankTarget].holdEffectParam;
- }
- else
- {
- defHoldEffect = ItemId_GetHoldEffect(defItem);
- defQuality = ItemId_GetHoldEffectParam(defItem);
- }
-
- switch (caseID)
- {
- case 0:
- switch (bankHoldEffect)
- {
- case HOLD_EFFECT_DOUBLE_PRIZE:
- gBattleStruct->moneyMultiplier = 2;
- break;
- case HOLD_EFFECT_RESTORE_STATS:
- for (i = 0; i < 8; i++)
- {
- if (gBattleMons[bank].statStages[i] < 6)
- {
- gBattleMons[bank].statStages[i] = 6;
- effect = ITEM_STATS_CHANGE;
- }
- }
- if (effect)
- {
- gBattleStruct->scriptingActive = bank;
- gStringBank = bank;
- gActiveBattler = gBankAttacker = bank;
- BattleScriptExecute(BattleScript_WhiteHerbEnd2);
- }
- break;
- }
- break;
- case 1:
- if (gBattleMons[bank].hp)
- {
- switch (bankHoldEffect)
- {
- case HOLD_EFFECT_RESTORE_HP:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn)
- {
- gBattleMoveDamage = bankQuality;
- if (gBattleMons[bank].hp + bankQuality > gBattleMons[bank].maxHP)
- gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp;
- gBattleMoveDamage *= -1;
- BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem);
- effect = 4;
- }
- break;
- case HOLD_EFFECT_RESTORE_PP:
- if (!moveTurn)
- {
- struct Pokemon* poke;
- u8 ppBonuses;
- u16 move;
-
- if (GetBattlerSide(bank) == 0)
- poke = &gPlayerParty[gBattlerPartyIndexes[bank]];
- else
- poke = &gEnemyParty[gBattlerPartyIndexes[bank]];
- for (i = 0; i < 4; i++)
- {
- move = GetMonData(poke, MON_DATA_MOVE1 + i);
- changedPP = GetMonData(poke, MON_DATA_PP1 + i);
- ppBonuses = GetMonData(poke, MON_DATA_PP_BONUSES);
- if (move && changedPP == 0)
- break;
- }
- if (i != 4)
- {
- u8 maxPP = CalculatePPWithBonus(move, ppBonuses, i);
- if (changedPP + bankQuality > maxPP)
- changedPP = maxPP;
- else
- changedPP = changedPP + bankQuality;
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 2;
- gBattleTextBuff1[2] = move;
- gBattleTextBuff1[3] = move >> 8;
- gBattleTextBuff1[4] = 0xFF;
- BattleScriptExecute(BattleScript_BerryPPHealEnd2);
- EmitSetMonData(0, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP);
- MarkBufferBankForExecution(gActiveBattler);
- effect = ITEM_PP_CHANGE;
- }
- }
- break;
- case HOLD_EFFECT_RESTORE_STATS:
- for (i = 0; i < 8; i++)
- {
- if (gBattleMons[bank].statStages[i] < 6)
- {
- gBattleMons[bank].statStages[i] = 6;
- effect = ITEM_STATS_CHANGE;
- }
- }
- if (effect)
- {
- gBattleStruct->scriptingActive = bank;
- gStringBank = bank;
- gActiveBattler = gBankAttacker = bank;
- BattleScriptExecute(BattleScript_WhiteHerbEnd2);
- }
- break;
- case HOLD_EFFECT_LEFTOVERS:
- if (gBattleMons[bank].hp < gBattleMons[bank].maxHP && !moveTurn)
- {
- gBattleMoveDamage = gBattleMons[bank].maxHP / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP)
- gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp;
- gBattleMoveDamage *= -1;
- BattleScriptExecute(BattleScript_ItemHealHP_End2);
- effect = ITEM_HP_CHANGE;
- RecordItemBattle(bank, bankHoldEffect);
- }
- break;
- // nice copy/paste there gamefreak, making a function for confuse berries was too much eh?
- case HOLD_EFFECT_CONFUSE_SPICY:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 8;
- gBattleTextBuff1[2] = FLAVOR_SPICY;
- gBattleTextBuff1[3] = EOS;
- gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP)
- gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp;
- gBattleMoveDamage *= -1;
- if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SPICY) < 0)
- BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
- else
- BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem);
- effect = ITEM_HP_CHANGE;
- }
- break;
- case HOLD_EFFECT_CONFUSE_DRY:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 8;
- gBattleTextBuff1[2] = FLAVOR_DRY;
- gBattleTextBuff1[3] = EOS;
- gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP)
- gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp;
- gBattleMoveDamage *= -1;
- if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_DRY) < 0)
- BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
- else
- BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem);
- effect = ITEM_HP_CHANGE;
- }
- break;
- case HOLD_EFFECT_CONFUSE_SWEET:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 8;
- gBattleTextBuff1[2] = FLAVOR_SWEET;
- gBattleTextBuff1[3] = EOS;
- gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP)
- gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp;
- gBattleMoveDamage *= -1;
- if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SWEET) < 0)
- BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
- else
- BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem);
- effect = ITEM_HP_CHANGE;
- }
- break;
- case HOLD_EFFECT_CONFUSE_BITTER:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 8;
- gBattleTextBuff1[2] = FLAVOR_BITTER;
- gBattleTextBuff1[3] = EOS;
- gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP)
- gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp;
- gBattleMoveDamage *= -1;
- if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_BITTER) < 0)
- BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
- else
- BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem);
- effect = ITEM_HP_CHANGE;
- }
- break;
- case HOLD_EFFECT_CONFUSE_SOUR:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 8;
- gBattleTextBuff1[2] = FLAVOR_SOUR;
- gBattleTextBuff1[3] = EOS;
- gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP)
- gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp;
- gBattleMoveDamage *= -1;
- if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SOUR) < 0)
- BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
- else
- BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem);
- effect = ITEM_HP_CHANGE;
- }
- break;
- // copy/paste again, smh
- case HOLD_EFFECT_ATTACK_UP:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_ATK] < 0xC)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 5;
- gBattleTextBuff1[2] = STAT_STAGE_ATK;
- gBattleTextBuff1[3] = EOS;
-
- gBattleTextBuff2[0] = 0xFD;
- gBattleTextBuff2[1] = 0;
- gBattleTextBuff2[2] = 0xD2;
- gBattleTextBuff2[3] = 0xD2 >> 8;
- gBattleTextBuff2[4] = EOS;
-
- gEffectBank = bank;
- gBattleStruct->statChanger = 0x10 + STAT_STAGE_ATK;
- gBattleStruct->animArg1 = 0xE + STAT_STAGE_ATK;
- gBattleStruct->animArg2 = 0;
- BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
- effect = ITEM_STATS_CHANGE;
- }
- break;
- case HOLD_EFFECT_DEFENSE_UP:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_DEF] < 0xC)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 5;
- gBattleTextBuff1[2] = STAT_STAGE_DEF;
- gBattleTextBuff1[3] = EOS;
-
- gEffectBank = bank;
- gBattleStruct->statChanger = 0x10 + STAT_STAGE_DEF;
- gBattleStruct->animArg1 = 0xE + STAT_STAGE_DEF;
- gBattleStruct->animArg2 = 0;
- BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
- effect = ITEM_STATS_CHANGE;
- }
- break;
- case HOLD_EFFECT_SPEED_UP:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 5;
- gBattleTextBuff1[2] = STAT_STAGE_SPEED;
- gBattleTextBuff1[3] = EOS;
-
- gEffectBank = bank;
- gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPEED;
- gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPEED;
- gBattleStruct->animArg2 = 0;
- BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
- effect = ITEM_STATS_CHANGE;
- }
- break;
- case HOLD_EFFECT_SP_ATTACK_UP:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPATK] < 0xC)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 5;
- gBattleTextBuff1[2] = STAT_STAGE_SPATK;
- gBattleTextBuff1[3] = EOS;
-
- gEffectBank = bank;
- gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPATK;
- gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPATK;
- gBattleStruct->animArg2 = 0;
- BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
- effect = ITEM_STATS_CHANGE;
- }
- break;
- case HOLD_EFFECT_SP_DEFENSE_UP:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPDEF] < 0xC)
- {
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 5;
- gBattleTextBuff1[2] = STAT_STAGE_SPDEF;
- gBattleTextBuff1[3] = EOS;
-
- gEffectBank = bank;
- gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPDEF;
- gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPDEF;
- gBattleStruct->animArg2 = 0;
- BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
- effect = ITEM_STATS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CRITICAL_UP:
- if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && !(gBattleMons[bank].status2 & STATUS2_FOCUS_ENERGY))
- {
- gBattleMons[bank].status2 |= STATUS2_FOCUS_ENERGY;
- BattleScriptExecute(BattleScript_BerryFocusEnergyEnd2);
- effect = ITEM_EFFECT_OTHER;
- }
- break;
- case HOLD_EFFECT_RANDOM_STAT_UP:
- if (!moveTurn && gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality)
- {
- for (i = 0; i < 5; i++)
- {
- if (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] < 0xC)
- break;
- }
- if (i != 5)
- {
- do
- {
- i = Random() % 5;
- } while (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] == 0xC);
-
- gBattleTextBuff1[0] = 0xFD;
- gBattleTextBuff1[1] = 5;
- gBattleTextBuff1[2] = i + 1;
- gBattleTextBuff1[3] = EOS;
-
- gBattleTextBuff2[0] = 0xFD;
- gBattleTextBuff2[1] = 0;
- gBattleTextBuff2[2] = 0xD1;
- gBattleTextBuff2[3] = 0xD1 >> 8;
- gBattleTextBuff2[4] = 0;
- gBattleTextBuff2[5] = 0xD2;
- gBattleTextBuff2[6] = 0xD2 >> 8;
- gBattleTextBuff2[7] = EOS;
-
- gEffectBank = bank;
- gBattleStruct->statChanger = 0x21 + i;
- gBattleStruct->animArg1 = 0x21 + i + 6;
- gBattleStruct->animArg2 = 0;
- BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
- effect = ITEM_STATS_CHANGE;
- }
- }
- break;
- case HOLD_EFFECT_CURE_PAR:
- if (gBattleMons[bank].status1 & STATUS_PARALYSIS)
- {
- gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS);
- BattleScriptExecute(BattleScript_BerryCurePrlzEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_PSN:
- if (gBattleMons[bank].status1 & STATUS_PSN_ANY)
- {
- gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER);
- BattleScriptExecute(BattleScript_BerryCurePsnEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_BRN:
- if (gBattleMons[bank].status1 & STATUS_BURN)
- {
- gBattleMons[bank].status1 &= ~(STATUS_BURN);
- BattleScriptExecute(BattleScript_BerryCureBrnEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_FRZ:
- if (gBattleMons[bank].status1 & STATUS_FREEZE)
- {
- gBattleMons[bank].status1 &= ~(STATUS_FREEZE);
- BattleScriptExecute(BattleScript_BerryCureFrzEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_SLP:
- if (gBattleMons[bank].status1 & STATUS_SLEEP)
- {
- gBattleMons[bank].status1 &= ~(STATUS_SLEEP);
- gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
- BattleScriptExecute(BattleScript_BerryCureSlpEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_CONFUSION:
- if (gBattleMons[bank].status2 & STATUS2_CONFUSION)
- {
- gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION);
- BattleScriptExecute(BattleScript_BerryCureConfusionEnd2);
- effect = ITEM_EFFECT_OTHER;
- }
- break;
- case HOLD_EFFECT_CURE_STATUS:
- if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION)
- {
- i = 0;
- if (gBattleMons[bank].status1 & STATUS_PSN_ANY)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
- i++;
- }
- if (gBattleMons[bank].status1 & STATUS_SLEEP)
- {
- gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
- StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
- i++;
- }
- if (gBattleMons[bank].status1 & STATUS_PARALYSIS)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
- i++;
- }
- if (gBattleMons[bank].status1 & STATUS_BURN)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
- i++;
- }
- if (gBattleMons[bank].status1 & STATUS_FREEZE)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
- i++;
- }
- if (gBattleMons[bank].status2 & STATUS2_CONFUSION)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
- i++;
- }
- if (!(i > 1))
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- else
- gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- gBattleMons[bank].status1 = 0;
- gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION);
- BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_ATTRACT:
- if (gBattleMons[bank].status2 & STATUS2_INFATUATION)
- {
- gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION);
- StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn);
- BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2);
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- effect = ITEM_EFFECT_OTHER;
- }
- break;
- }
- if (effect)
- {
- gBattleStruct->scriptingActive = bank;
- gStringBank = bank;
- gActiveBattler = gBankAttacker = bank;
- switch (effect)
- {
- case ITEM_STATUS_CHANGE:
- EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1);
- MarkBufferBankForExecution(gActiveBattler);
- break;
- case ITEM_PP_CHANGE:
- if (!(gBattleMons[bank].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[bank].unk18_b & gBitTable[i]))
- gBattleMons[bank].pp[i] = changedPP;
- break;
- }
- }
- }
- break;
- case 2:
- break;
- case 3:
- for (bank = 0; bank < gBattlersCount; bank++)
- {
- gLastUsedItem = gBattleMons[bank].item;
- if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY)
- {
- bankHoldEffect = gEnigmaBerries[bank].holdEffect;
- bankQuality = gEnigmaBerries[bank].holdEffectParam;
- }
- else
- {
- bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem);
- bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem);
- }
- switch (bankHoldEffect)
- {
- case HOLD_EFFECT_CURE_PAR:
- if (gBattleMons[bank].status1 & STATUS_PARALYSIS)
- {
- gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_BerryCureParRet;
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_PSN:
- if (gBattleMons[bank].status1 & STATUS_PSN_ANY)
- {
- gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet;
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_BRN:
- if (gBattleMons[bank].status1 & STATUS_BURN)
- {
- gBattleMons[bank].status1 &= ~(STATUS_BURN);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet;
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_FRZ:
- if (gBattleMons[bank].status1 & STATUS_FREEZE)
- {
- gBattleMons[bank].status1 &= ~(STATUS_FREEZE);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet;
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_SLP:
- if (gBattleMons[bank].status1 & STATUS_SLEEP)
- {
- gBattleMons[bank].status1 &= ~(STATUS_SLEEP);
- gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet;
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_CURE_CONFUSION:
- if (gBattleMons[bank].status2 & STATUS2_CONFUSION)
- {
- gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION);
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet;
- effect = ITEM_EFFECT_OTHER;
- }
- break;
- case HOLD_EFFECT_CURE_ATTRACT:
- if (gBattleMons[bank].status2 & STATUS2_INFATUATION)
- {
- gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION);
- StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn);
- BattleScriptPushCursor();
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet;
- effect = ITEM_EFFECT_OTHER;
- }
- break;
- case HOLD_EFFECT_CURE_STATUS:
- if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION)
- {
- if (gBattleMons[bank].status1 & STATUS_PSN_ANY)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
- }
- if (gBattleMons[bank].status1 & STATUS_SLEEP)
- {
- gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
- StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
- }
- if (gBattleMons[bank].status1 & STATUS_PARALYSIS)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
- }
- if (gBattleMons[bank].status1 & STATUS_BURN)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
- }
- if (gBattleMons[bank].status1 & STATUS_FREEZE)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
- }
- if (gBattleMons[bank].status2 & STATUS2_CONFUSION)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
- }
- gBattleMons[bank].status1 = 0;
- gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION);
- BattleScriptPushCursor();
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet;
- effect = ITEM_STATUS_CHANGE;
- }
- break;
- case HOLD_EFFECT_RESTORE_STATS:
- for (i = 0; i < 8; i++)
- {
- if (gBattleMons[bank].statStages[i] < 6)
- {
- gBattleMons[bank].statStages[i] = 6;
- effect = ITEM_STATS_CHANGE;
- }
- }
- if (effect)
- {
- gBattleStruct->scriptingActive = bank;
- gStringBank = bank;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_WhiteHerbRet;
- return effect; // unnecessary return
- }
- break;
- }
- if (effect)
- {
- gBattleStruct->scriptingActive = bank;
- gStringBank = bank;
- gActiveBattler = bank;
- EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
- MarkBufferBankForExecution(gActiveBattler);
- break;
- }
- }
- break;
- case 4:
- if (gBattleMoveDamage)
- {
- switch (atkHoldEffect)
- {
- case HOLD_EFFECT_FLINCH:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)
- && (Random() % 100) < bankQuality
- && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_KINGS_ROCK
- && gBattleMons[gBankTarget].hp)
- {
- gBattleCommunication[MOVE_EFFECT_BYTE] = 8;
- BattleScriptPushCursor();
- SetMoveEffect(0, 0);
- BattleScriptPop();
- }
- break;
- case HOLD_EFFECT_SHELL_BELL:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gSpecialStatuses[gBankTarget].moveturnLostHP != 0
- && gSpecialStatuses[gBankTarget].moveturnLostHP != 0xFFFF
- && gBankAttacker != gBankTarget
- && gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP
- && gBattleMons[gBankAttacker].hp != 0)
- {
- gLastUsedItem = atkItem;
- gStringBank = gBankAttacker;
- gBattleStruct->scriptingActive = gBankAttacker;
- gBattleMoveDamage = (gSpecialStatuses[gBankTarget].moveturnLostHP / atkQuality) * -1;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = -1;
- gSpecialStatuses[gBankTarget].moveturnLostHP = 0;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret;
- effect++;
- }
- break;
- }
- }
- break;
- }
-
- return effect;
-}
-
-struct CombinedMove
-{
- u16 move1;
- u16 move2;
- u16 newMove;
-};
-
-static const struct CombinedMove sCombinedMoves[2] =
-{
- {MOVE_EMBER, MOVE_GUST, MOVE_HEAT_WAVE},
- {0xFFFF, 0xFFFF, 0xFFFF}
-};
-
-void unref_sub_801B40C(void)
-{
- int i = 0;
- if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- {
- do
- {
- u8 bank = 0;
- do
- {
- u8 absent = gAbsentBattlerFlags;
- if (gBitTable[bank] & absent || absent & gBitTable[bank + 2])
- bank++;
- else
- {
- if (sCombinedMoves[i].move1 == gChosenMovesByBanks[bank] && sCombinedMoves[i].move2 == gChosenMovesByBanks[bank + 2])
- {
- gSideTimers[GetBattlerPosition(bank) & 1].field3 = (bank) | ((bank + 2) << 4);
- gSideTimers[GetBattlerPosition(bank) & 1].field4 = sCombinedMoves[i].newMove;
- gSideAffecting[GetBattlerPosition(bank) & 1] |= SIDE_STATUS_X4;
- }
- if (sCombinedMoves[i].move1 == gChosenMovesByBanks[bank + 2] && sCombinedMoves[i].move2 == gChosenMovesByBanks[bank])
- {
- gSideTimers[GetBattlerPosition(bank) & 1].field3 = (bank + 2) | ((bank) << 4);
- gSideTimers[GetBattlerPosition(bank) & 1].field4 = sCombinedMoves[i].newMove;
- gSideAffecting[GetBattlerPosition(bank) & 1] |= SIDE_STATUS_X4;
- }
- bank++;
- }
- } while (bank < 2);
- i++;
- } while (sCombinedMoves[i].move1 != 0xFFFF);
- }
-}
-
-void sub_801B594(void)
-{
- if (gBattleExecBuffer == 0)
- gBattleScriptingCommandsTable[*gBattlescriptCurrInstr]();
-}
-
-u8 GetMoveTarget(u16 move, u8 useMoveTarget) //get move target
-{
- u8 targetBank = 0;
- u8 moveTarget;
- u8 side;
-
- if (useMoveTarget)
- moveTarget = useMoveTarget - 1;
- else
- moveTarget = gBattleMoves[move].target;
-
- switch (moveTarget)
- {
- case 0:
- side = GetBattlerSide(gBankAttacker) ^ 1;
- if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp)
- targetBank = gSideTimers[side].followmeTarget;
- else
- {
- side = GetBattlerSide(gBankAttacker);
- do
- {
- targetBank = Random() % gBattlersCount;
- } while (targetBank == gBankAttacker || side == GetBattlerSide(targetBank) || gAbsentBattlerFlags & gBitTable[targetBank]);
- if (gBattleMoves[move].type == TYPE_ELECTRIC
- && AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_LIGHTNING_ROD, 0, 0)
- && gBattleMons[targetBank].ability != ABILITY_LIGHTNING_ROD)
- {
- targetBank ^= 2;
- RecordAbilityBattle(targetBank, gBattleMons[targetBank].ability);
- gSpecialStatuses[targetBank].lightningRodRedirected = 1;
- }
- }
- break;
- case 1:
- case 8:
- case 32:
- case 64:
- targetBank = GetBattlerAtPosition((GetBattlerPosition(gBankAttacker) & 1) ^ 1);
- if (gAbsentBattlerFlags & gBitTable[targetBank])
- targetBank ^= 2;
- break;
- case 4:
- side = GetBattlerSide(gBankAttacker) ^ 1;
- if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp)
- targetBank = gSideTimers[side].followmeTarget;
- else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & 4)
- {
- if (GetBattlerSide(gBankAttacker) == 0)
- {
- if (Random() & 1)
- targetBank = GetBattlerAtPosition(1);
- else
- targetBank = GetBattlerAtPosition(3);
- }
- else
- {
- if (Random() & 1)
- targetBank = GetBattlerAtPosition(0);
- else
- targetBank = GetBattlerAtPosition(2);
- }
- if (gAbsentBattlerFlags & gBitTable[targetBank])
- targetBank ^= 2;
- }
- else
- targetBank = GetBattlerAtPosition((GetBattlerPosition(gBankAttacker) & 1) ^ 1);
- break;
- case 2:
- case 16:
- targetBank = gBankAttacker;
- break;
- }
- ewram16010arr(gBankAttacker) = targetBank;
- return targetBank;
-}
-
-u8 IsMonDisobedient(void)
-{
- u8 obedienceLevel;
- s32 rnd;
- s32 calc;
-
- if (gBattleTypeFlags & BATTLE_TYPE_LINK
- || GetBattlerSide(gBankAttacker) == 1
- || !IsOtherTrainer(gBattleMons[gBankAttacker].otId, gBattleMons[gBankAttacker].otName))
- return 0;
-
- if (DEBUG && (gUnknown_02023A14_50 & 0x40))
- {
- obedienceLevel = 10;
- }
- else
- {
- if (FlagGet(FLAG_BADGE08_GET))
- return 0;
- obedienceLevel = 10;
- if (FlagGet(FLAG_BADGE02_GET))
- obedienceLevel = 30;
- if (FlagGet(FLAG_BADGE04_GET))
- obedienceLevel = 50;
- if (FlagGet(FLAG_BADGE06_GET))
- obedienceLevel = 70;
- }
-
- if (gBattleMons[gBankAttacker].level <= obedienceLevel)
- return 0;
- rnd = (Random() & 255);
- calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8;
- if (calc < obedienceLevel)
- return 0;
-
- // is not obedient
- if (gCurrentMove == MOVE_RAGE)
- gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RAGE);
- if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK))
- {
- gBattlescriptCurrInstr = gUnknown_081D995F;
- return 1;
- }
-
- rnd = (Random() & 255);
- calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8;
- if (calc < obedienceLevel)
- {
- calc = CheckMoveLimitations(gBankAttacker, gBitTable[gCurrMovePos], 0xFF);
- if (calc == 0xF) // all moves cannot be used
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3;
- gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
- return 1;
- }
- else // use a random move
- {
- do
- {
- gCurrMovePos = gUnknown_02024BE5 = Random() & 3;
- } while (gBitTable[gCurrMovePos] & calc);
- gRandomMove = gBattleMons[gBankAttacker].moves[gCurrMovePos];
- gBattleCommunication[3] = 0;
- gDynamicBasePower = 0;
- gBattleStruct->dynamicMoveType = 0;
- gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
- gBankTarget = GetMoveTarget(gRandomMove, 0);
- gHitMarker |= HITMARKER_x200000;
- return 2;
- }
- }
- else
- {
- obedienceLevel = gBattleMons[gBankAttacker].level - obedienceLevel;
-
- calc = (Random() & 255);
- if (calc < obedienceLevel && !(gBattleMons[gBankAttacker].status1 & STATUS_ANY) && gBattleMons[gBankAttacker].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gBankAttacker].ability != ABILITY_INSOMNIA)
- {
- // try putting asleep
- int i;
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattleMons[i].status2 & STATUS2_UPROAR)
- break;
- }
- if (i == gBattlersCount)
- {
- gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep;
- return 1;
- }
- }
- calc -= obedienceLevel;
- if (calc < obedienceLevel)
- {
- gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker);
- gBankTarget = gBankAttacker;
- gBattlescriptCurrInstr = gUnknown_081D99A0;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- return 2;
- }
- else
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3;
- gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
- return 1;
- }
- }
-}