diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 6838cdba8..40ad9553c 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -1008,17 +1008,26 @@ Move_U_TURN: playsewithpan SE_W019, SOUND_PAN_ATTACKER createsprite gFlyBallUpSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 13, 336 playsewithpan SE_W104, SOUND_PAN_ATTACKER + createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER + jumpretfalse UTurnVisible createsprite gFlyBallAttackSpriteTemplate, ANIM_ATTACKER, 2, 20, TRUE +UTurnContinue: delay 20 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 1, 0 createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1 playsewithpan SE_W013, SOUND_PAN_TARGET waitforvisualfinish clearmonbg ANIM_DEF_PARTNER + createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER + jumpretfalse UTurnLast invisible ANIM_ATTACKER +UTurnLast: blendoff waitforvisualfinish end +UTurnVisible: + createsprite gFlyBallAttackSpriteTemplate, ANIM_ATTACKER, 2, 20, FALSE + goto UTurnContinue Move_CLOSE_COMBAT: loadspritegfx ANIM_TAG_IMPACT @@ -4518,13 +4527,26 @@ Move_VOLT_SWITCH: delay 4 call ElectricityEffect playsewithpan SE_W085B, SOUND_PAN_ATTACKER + createvisualtask AnimTask_CanBattlerSwitch 1, ANIM_ATTACKER + jumpretfalse VoltSwitchContinue + createvisualtask AnimTask_IsTargetSameSide 1 + jumprettrue VoltSwitchAgainstPartner createvisualtask AnimTask_SlideOffScreen, 5, ANIM_ATTACKER, -2 +VoltSwitchContinue: waitforvisualfinish clearmonbg ANIM_ATTACKER blendoff + createvisualtask AnimTask_CanBattlerSwitch 1, ANIM_ATTACKER + jumpretfalse VoltSwitchLast invisible ANIM_ATTACKER +VoltSwitchLast: delay 8 end +@ Attacking the same side requires a change of direction +@ why would you attack your partner though?! +VoltSwitchAgainstPartner: + createvisualtask AnimTask_SlideOffScreen, 5, ANIM_ATTACKER, +2 + goto VoltSwitchContinue Move_STRUGGLE_BUG: end diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index ab2217712..8fec39df3 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -8,6 +8,7 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi u8 GetBattlerTurnOrderNum(u8 battlerId); bool32 NoAliveMonsForEitherParty(void); void SetMoveEffect(bool32 primary, u32 certain); +bool32 CanBattlerSwitch(u32 battlerId); void BattleDestroyYesNoCursorAt(u8 cursorPosition); void BattleCreateYesNoCursorAt(u8 cursorPosition); void BufferMoveToLearnIntoBattleTextBuff2(void); diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c index 60a63ff7d..5dbd22023 100644 --- a/src/battle_anim_utility_funcs.c +++ b/src/battle_anim_utility_funcs.c @@ -1070,3 +1070,9 @@ void AnimTask_IsDoubleBattle(u8 taskId) gBattleAnimArgs[7] = (IsDoubleBattle() && !IsContest()); DestroyAnimVisualTask(taskId); } + +void AnimTask_CanBattlerSwitch(u8 taskId) +{ + gBattleAnimArgs[ARG_RET_ID] = CanBattlerSwitch(GetAnimBattlerId(gBattleAnimArgs[0])); + DestroyAnimVisualTask(taskId); +} diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 3eeebe09c..09567dd16 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4953,22 +4953,13 @@ static void Cmd_switchinanim(void) BattleArena_InitPoints(); } -static void Cmd_jumpifcantswitch(void) +bool32 CanBattlerSwitch(u32 battlerId) { - s32 i; - s32 lastMonId; - u8 battlerIn1, battlerIn2; + s32 i, lastMonId, battlerIn1, battlerIn2; + bool32 ret = FALSE; struct Pokemon *party; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(SWITCH_IGNORE_ESCAPE_PREVENTION)); - - if (!(gBattlescriptCurrInstr[1] & SWITCH_IGNORE_ESCAPE_PREVENTION) - && ((gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) - || (gStatuses3[gActiveBattler] & STATUS3_ROOTED))) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - } - else if (BATTLE_TWO_VS_ONE_OPPONENT && GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) + if (BATTLE_TWO_VS_ONE_OPPONENT && GetBattlerSide(battlerId) == B_SIDE_OPPONENT) { battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); @@ -4983,20 +4974,17 @@ static void Cmd_jumpifcantswitch(void) break; } - if (i == PARTY_SIZE) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; + ret = (i != PARTY_SIZE); } else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) { - if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) party = gEnemyParty; else party = gPlayerParty; i = 0; - if (gActiveBattler & 2) + if (battlerId & 2) i = 3; for (lastMonId = i + 3; i < lastMonId; i++) @@ -5004,32 +4992,29 @@ static void Cmd_jumpifcantswitch(void) if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE && !GetMonData(&party[i], MON_DATA_IS_EGG) && GetMonData(&party[i], MON_DATA_HP) != 0 - && gBattlerPartyIndexes[gActiveBattler] != i) + && gBattlerPartyIndexes[battlerId] != i) break; } - if (i == lastMonId) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; + ret = (i != lastMonId); } else if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { if (gBattleTypeFlags & BATTLE_TYPE_x800000) { - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { party = gPlayerParty; i = 0; - if (GetLinkTrainerFlankId(GetBattlerMultiplayerId(gActiveBattler)) == TRUE) + if (GetLinkTrainerFlankId(GetBattlerMultiplayerId(battlerId)) == TRUE) i = 3; } else { party = gEnemyParty; - if (gActiveBattler == 1) + if (battlerId == 1) i = 0; else i = 3; @@ -5037,13 +5022,13 @@ static void Cmd_jumpifcantswitch(void) } else { - if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) party = gEnemyParty; else party = gPlayerParty; i = 0; - if (GetLinkTrainerFlankId(GetBattlerMultiplayerId(gActiveBattler)) == TRUE) + if (GetLinkTrainerFlankId(GetBattlerMultiplayerId(battlerId)) == TRUE) i = 3; } @@ -5052,21 +5037,18 @@ static void Cmd_jumpifcantswitch(void) if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE && !GetMonData(&party[i], MON_DATA_IS_EGG) && GetMonData(&party[i], MON_DATA_HP) != 0 - && gBattlerPartyIndexes[gActiveBattler] != i) + && gBattlerPartyIndexes[battlerId] != i) break; } - if (i == lastMonId) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; + ret = (i != lastMonId); } - else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && GetBattlerSide(battlerId) == B_SIDE_OPPONENT) { party = gEnemyParty; i = 0; - if (gActiveBattler == B_POSITION_OPPONENT_RIGHT) + if (battlerId == B_POSITION_OPPONENT_RIGHT) i = 3; for (lastMonId = i + 3; i < lastMonId; i++) @@ -5074,18 +5056,15 @@ static void Cmd_jumpifcantswitch(void) if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE && !GetMonData(&party[i], MON_DATA_IS_EGG) && GetMonData(&party[i], MON_DATA_HP) != 0 - && gBattlerPartyIndexes[gActiveBattler] != i) + && gBattlerPartyIndexes[battlerId] != i) break; } - if (i == lastMonId) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; + ret = (i != lastMonId); } else { - if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) { battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); @@ -5117,10 +5096,27 @@ static void Cmd_jumpifcantswitch(void) break; } - if (i == 6) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else + ret = (i != PARTY_SIZE); + } + return ret; +} + +static void Cmd_jumpifcantswitch(void) +{ + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(SWITCH_IGNORE_ESCAPE_PREVENTION)); + + if (!(gBattlescriptCurrInstr[1] & SWITCH_IGNORE_ESCAPE_PREVENTION) + && ((gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + || (gStatuses3[gActiveBattler] & STATUS3_ROOTED))) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + } + else + { + if (CanBattlerSwitch(gActiveBattler)) gBattlescriptCurrInstr += 6; + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); } }