diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 1935e87a7..146fea5cc 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1980,6 +1980,14 @@ various BS_ATTACKER, VARIOUS_SWAP_SIDE_STATUSES .endm + .macro canteleport battler:req + various \battler, VARIOUS_CAN_TELEPORT + .endm + + .macro getbattlerside battler:req + various \battler, VARIOUS_GET_BATTLER_SIDE + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 96f832d85..c3bf65edb 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5176,7 +5176,14 @@ BattleScript_EffectTeleport: attackcanceler attackstring ppreduce +.if B_TELEPORT_BEHAVIOR >= GEN_7 + canteleport BS_ATTACKER + jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_EffectTeleportNew + goto BattleScript_ButItFailed +.else jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_ButItFailed +.endif +BattleScript_EffectTeleportTryToRunAway: getifcantrunfrombattle BS_ATTACKER jumpifbyte CMP_EQUAL, gBattleCommunication, BATTLE_RUN_FORBIDDEN, BattleScript_ButItFailed jumpifbyte CMP_EQUAL, gBattleCommunication, BATTLE_RUN_FAILURE, BattleScript_PrintAbilityMadeIneffective @@ -5187,6 +5194,29 @@ BattleScript_EffectTeleport: setoutcomeonteleport BS_ATTACKER goto BattleScript_MoveEnd +BattleScript_EffectTeleportNew: + getbattlerside BS_ATTACKER + jumpifbyte CMP_EQUAL, gBattleCommunication, B_SIDE_OPPONENT, BattleScript_EffectTeleportTryToRunAway + attackanimation + waitanimation + openpartyscreen BS_ATTACKER, BattleScript_EffectTeleportNewEnd + switchoutabilities BS_ATTACKER + waitstate + switchhandleorder BS_ATTACKER, 2 + returntoball BS_ATTACKER + getswitchedmondata BS_ATTACKER + switchindataupdate BS_ATTACKER + hpthresholds BS_ATTACKER + trytoclearprimalweather + printstring STRINGID_EMPTYSTRING3 + waitmessage 1 + printstring STRINGID_SWITCHINMON + switchinanim BS_ATTACKER, TRUE + waitstate + switchineffects BS_ATTACKER +BattleScript_EffectTeleportNewEnd: + goto BattleScript_MoveEnd + BattleScript_EffectBeatUp:: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index dfd4fd3d0..a102f926a 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -87,6 +87,7 @@ // Draining abilities will not heal but will prevent damage. In Gen6+, Heal Block prevents the use of most HP-draining moves. #define B_ROOTED_GROUNDING GEN_LATEST // In Gen4+, Ingrain causes the affected Pokémon to become grounded. #define B_METRONOME_MOVES GEN_LATEST // This config will determine up to which generation will Metronome pull moves from. +#define B_TELEPORT_BEHAVIOR GEN_LATEST // In Gen7+, starting with Pokémon LGPE, Teleport allows the user to swap out with another party member. // Ability settings #define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters. diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index e9a091129..b11e7eb65 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -243,6 +243,8 @@ #define VARIOUS_SWAP_SIDE_STATUSES 152 #define VARIOUS_SET_Z_EFFECT 153 #define VARIOUS_TRY_SYMBIOSIS 154 +#define VARIOUS_CAN_TELEPORT 155 +#define VARIOUS_GET_BATTLER_SIDE 156 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 053df731f..bb3fc1c0f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8021,6 +8021,38 @@ static bool32 CourtChangeSwapSideStatuses(void) SWAP(sideTimerPlayer->stickyWebBattlerSide, sideTimerOpp->stickyWebBattlerSide, temp); } +static bool32 CanTeleport(u8 battlerId) +{ + struct Pokemon* party = NULL; + u32 species, count, i; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + for (i = 0; i < PARTY_SIZE; i++) + { + species = GetMonData(&party[i], MON_DATA_SPECIES2); + if (species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(&party[i], MON_DATA_HP) != 0) + count++; + } + + switch (GetBattlerSide(battlerId)) + { + case B_SIDE_OPPONENT: + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + return FALSE; + break; + case B_SIDE_PLAYER: + if (count == 1 || (count <= 2 && gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + return FALSE; + break; + } + + return TRUE; +} + static void Cmd_various(void) { struct Pokemon *mon; @@ -9857,6 +9889,15 @@ static void Cmd_various(void) return; } break; + case VARIOUS_CAN_TELEPORT: + gBattleCommunication[0] = CanTeleport(gActiveBattler); + break; + case VARIOUS_GET_BATTLER_SIDE: + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + gBattleCommunication[0] = B_SIDE_PLAYER; + else + gBattleCommunication[0] = B_SIDE_OPPONENT; + break; } // End of switch (gBattlescriptCurrInstr[2]) gBattlescriptCurrInstr += 3;