diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 36edbbde81..852150a637 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -348,6 +348,7 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectMatBlock .4byte BattleScript_EffectStompingTantrum .4byte BattleScript_EffectCoreEnforcer + .4byte BattleScript_EffectThroatChop BattleScript_EffectCoreEnforcer: setmoveeffect MOVE_EFFECT_CORE_ENFORCER | MOVE_EFFECT_CERTAIN @@ -1685,7 +1686,12 @@ BattleScript_EffectHealBlock: printstring STRINGID_PKMNPREVENTEDFROMHEALING waitmessage 0x40 goto BattleScript_MoveEnd - + +BattleScript_EffectThroatChop: + jumpifsubstituteblocks BattleScript_EffectHit + setmoveeffect MOVE_EFFECT_THROAT_CHOP | MOVE_EFFECT_CERTAIN + goto BattleScript_EffectHit + BattleScript_EffectHitEscape: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE @@ -5391,7 +5397,25 @@ BattleScript_MoveUsedIsTaunted:: BattleScript_SelectingNotAllowedMoveTauntInPalace:: printstring STRINGID_PKMNCANTUSEMOVETAUNT goto BattleScript_SelectingUnusableMoveInPalace + +BattleScript_SelectingNotAllowedMoveThroatChop:: + printselectionstring STRINGID_PKMNCANTUSEMOVETHROATCHOP + endselectionscript + +BattleScript_MoveUsedIsThroatChopPrevented:: + printstring STRINGID_PKMNCANTUSEMOVETHROATCHOP + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_SelectingNotAllowedMoveThroatChopInPalace:: + printstring STRINGID_PKMNCANTUSEMOVETHROATCHOP + goto BattleScript_SelectingUnusableMoveInPalace +BattleScript_ThroatChopEndTurn:: + printstring STRINGID_THROATCHOPENDS + waitmessage 0x40 + end2 + BattleScript_SelectingNotAllowedMoveGravity:: printselectionstring STRINGID_GRAVITYPREVENTSUSAGE endselectionscript diff --git a/include/battle.h b/include/battle.h index 8e74501a15..c6cf49fc25 100644 --- a/include/battle.h +++ b/include/battle.h @@ -111,6 +111,7 @@ struct DisableStruct u8 telekinesisTimer; u8 healBlockTimer; u8 laserFocusTimer; + u8 throatChopTimer; u8 usedMoves:4; u8 wrapTurns; }; @@ -143,6 +144,7 @@ struct ProtectStruct u32 usedHealBlockedMove:1; u32 usedGravityPreventedMove:1; u32 powderSelfDmg:1; + u32 usedThroatChopPreventedMove:1; u32 physicalDmg; u32 specialDmg; u8 physicalBattlerId; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index a9d45d21fc..cf8504f6c0 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -305,5 +305,9 @@ extern const u8 BattleScript_BanefulBunkerEffect[]; extern const u8 BattleScript_FlowerVeilProtectsRet[]; extern const u8 BattleScript_SweetVeilProtectsRet[]; extern const u8 BattleScript_MoveEffectCoreEnforcer[]; +extern const u8 BattleScript_SelectingNotAllowedMoveThroatChop[]; +extern const u8 BattleScript_MoveUsedIsThroatChopPrevented[]; +extern const u8 BattleScript_SelectingNotAllowedMoveThroatChopInPalace[]; +extern const u8 BattleScript_ThroatChopEndTurn[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle.h b/include/constants/battle.h index b97b7b769d..42b80d173f 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -329,6 +329,7 @@ #define MOVE_EFFECT_V_CREATE 0x40 #define MOVE_EFFECT_HAPPY_HOUR 0x41 #define MOVE_EFFECT_CORE_ENFORCER 0x42 +#define MOVE_EFFECT_THROAT_CHOP 0x43 #define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_CERTAIN 0x8000 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 95d370fae2..7da5079f3a 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -337,4 +337,7 @@ #define EFFECT_STOMPING_TANTRUM 331 #define EFFECT_CORE_ENFORCER 332 + +#define EFFECT_THROAT_CHOP 334 + #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 5114102f7c..b4a408ca2d 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -529,6 +529,9 @@ #define STRINGID_AROMAVEILPROTECTED 525 #define STRINGID_CELEBRATEMESSAGE 526 -#define BATTLESTRINGS_COUNT 529 +#define STRINGID_THROATCHOPENDS 528 +#define STRINGID_PKMNCANTUSEMOVETHROATCHOP 529 + +#define BATTLESTRINGS_COUNT 530 #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H diff --git a/src/battle_main.c b/src/battle_main.c index 695be6470d..bca4f26a7e 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3113,6 +3113,7 @@ void FaintClearSetData(void) gProtectStructs[gActiveBattler].usedHealBlockedMove = 0; gProtectStructs[gActiveBattler].usesBouncedMove = 0; gProtectStructs[gActiveBattler].usedGravityPreventedMove = 0; + gProtectStructs[gActiveBattler].usedThroatChopPreventedMove = 0; gDisableStructs[gActiveBattler].isFirstTurn = 2; diff --git a/src/battle_message.c b/src/battle_message.c index 6a3c63ac79..055f1ff668 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -261,6 +261,7 @@ static const u8 sText_PkmnMoveIsDisabled[] = _("{B_ACTIVE_NAME_WITH_PREFIX}'s {B static const u8 sText_PkmnCantUseMoveTorment[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can't use the same\nmove in a row due to the Torment!\p"); static const u8 sText_PkmnCantUseMoveTaunt[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can't use\n{B_CURRENT_MOVE} after the Taunt!\p"); static const u8 sText_PkmnCantUseMoveSealed[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can't use the\nsealed {B_CURRENT_MOVE}!\p"); +static const u8 sText_PkmnCantUseMoveThroatChop[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can't use\n{B_CURRENT_MOVE} due to Throat Chop!\p"); static const u8 sText_PkmnMadeItRain[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nmade it rain!"); static const u8 sText_PkmnRaisedSpeed[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nraised its SPEED!"); static const u8 sText_PkmnProtectedBy[] = _("{B_DEF_NAME_WITH_PREFIX} was protected\nby {B_DEF_ABILITY}!"); @@ -558,9 +559,10 @@ static const u8 sText_FreedFromSkyDrop[] =_("{B_DEF_NAME_WITH_PREFIX} was freed\ static const u8 sText_PostponeTargetMove[] =_("{B_DEF_NAME_WITH_PREFIX}'s move\nwas postponed!"); static const u8 sText_ReflectTargetsType[] =_("{B_ATK_NAME_WITH_PREFIX}'s type\nchanged to match the {B_DEF_NAME_WITH_PREFIX}'s!"); static const u8 sText_TransferHeldItem[] =_("{B_DEF_NAME_WITH_PREFIX} recieved {B_LAST_ITEM}\nfrom {B_ATK_NAME_WITH_PREFIX}"); -static const u8 sText_EmbargoEnds[] = _("{B_DEF_NAME_WITH_PREFIX}can\nuse items again!"); +static const u8 sText_EmbargoEnds[] = _("{B_ATK_NAME_WITH_PREFIX} can\nuse items again!"); static const u8 sText_Electromagnetism[] = _("electromagnetism"); static const u8 sText_BufferEnds[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1}\nwore off!"); +static const u8 sText_ThroatChopEnds[] = _("{B_ATK_NAME_WITH_PREFIX} can\nuse sound-based moves again!"); static const u8 sText_TelekinesisEnds[] = _("{B_ATK_NAME_WITH_PREFIX} was freed\nfrom the telekinesis!"); static const u8 sText_TailwindEnds[] = _("{B_ATK_TEAM1} team's tailwind\n petered out!"); static const u8 sText_LuckyChantEnds[] = _("{B_ATK_TEAM1} team's Lucky Chant\n wore off!"); @@ -656,6 +658,9 @@ static const u8 sText_CelebrateMessage[] = _("Congratulations, {B_PLAYER_NAME}!" const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_THROATCHOPENDS - 12] = sText_ThroatChopEnds, + [STRINGID_PKMNCANTUSEMOVETHROATCHOP - 12] = sText_PkmnCantUseMoveThroatChop, + [STRINGID_CELEBRATEMESSAGE - 12] = sText_CelebrateMessage, [STRINGID_AROMAVEILPROTECTED - 12] = sText_AromaVeilProtected, [STRINGID_SWEETVEILPROTECTED - 12] = sText_SweetVeilProtected, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a7db5d336d..b066c19d5a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2816,6 +2816,10 @@ void SetMoveEffect(bool32 primary, u32 certain) gBattlescriptCurrInstr = BattleScript_MoveEffectCoreEnforcer; } break; + case MOVE_EFFECT_THROAT_CHOP: + gDisableStructs[gEffectBattler].throatChopTimer = 2; + gBattlescriptCurrInstr++; + break; } } } diff --git a/src/battle_util.c b/src/battle_util.c index ae0f7dd3f8..3e4b1b4f09 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -468,7 +468,8 @@ bool8 WasUnableToUseMove(u8 battler) || gProtectStructs[battler].flag2Unknown || gProtectStructs[battler].flinchImmobility || gProtectStructs[battler].confusionSelfDmg - || gProtectStructs[battler].powderSelfDmg) + || gProtectStructs[battler].powderSelfDmg + || gProtectStructs[battler].usedThroatChopPreventedMove) return TRUE; else return FALSE; @@ -679,6 +680,21 @@ u8 TrySetCantSelectMoveBattleScript(void) } } + if (gDisableStructs[gActiveBattler].throatChopTimer != 0 && gBattleMoves[move].flags & FLAG_SOUND) + { + gCurrentMove = move; + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveThroatChopInPalace; + gProtectStructs[gActiveBattler].palaceUnableToUseMove = 1; + } + else + { + gSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveThroatChop; + limitations++; + } + } + if (GetImprisonedMovesCount(gActiveBattler, move)) { gCurrentMove = move; @@ -819,6 +835,8 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check) unusableMoves |= gBitTable[i]; else if (IsBelchPreventingMove(battlerId, gBattleMons[battlerId].moves[i])) unusableMoves |= gBitTable[i]; + else if (gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND) + unusableMoves |= gBitTable[i]; } return unusableMoves; } @@ -1346,6 +1364,7 @@ enum ENDTURN_ROOST, ENDTURN_ELECTRIFY, ENDTURN_POWDER, + ENDTURN_THROAT_CHOP, ENDTURN_BATTLER_COUNT }; @@ -1786,6 +1805,14 @@ u8 DoBattlerEndTurnEffects(void) case ENDTURN_POWDER: gBattleMons[gActiveBattler].status2 &= ~(STATUS2_POWDER); gBattleStruct->turnEffectsTracker++; + case ENDTURN_THROAT_CHOP: + if (gDisableStructs[gActiveBattler].throatChopTimer && --gDisableStructs[gActiveBattler].throatChopTimer == 0) + { + BattleScriptExecute(BattleScript_ThroatChopEndTurn); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; case ENDTURN_BATTLER_COUNT: // done gBattleStruct->turnEffectsTracker = 0; gBattleStruct->turnEffectsBattlerId++; @@ -1995,27 +2022,28 @@ void TryClearRageAndFuryCutter(void) enum { - CANCELLER_FLAGS, - CANCELLER_ASLEEP, - CANCELLER_FROZEN, - CANCELLER_TRUANT, - CANCELLER_RECHARGE, - CANCELLER_FLINCH, - CANCELLER_DISABLED, - CANCELLER_GRAVITY, - CANCELLER_HEAL_BLOCKED, - CANCELLER_TAUNTED, - CANCELLER_IMPRISONED, - CANCELLER_CONFUSED, - CANCELLER_PARALYSED, - CANCELLER_IN_LOVE, - CANCELLER_BIDE, - CANCELLER_THAW, - CANCELLER_POWDER_MOVE, - CANCELLER_POWDER_STATUS, - CANCELLER_END, - CANCELLER_PSYCHIC_TERRAIN, - CANCELLER_END2, + CANCELLER_FLAGS, + CANCELLER_ASLEEP, + CANCELLER_FROZEN, + CANCELLER_TRUANT, + CANCELLER_RECHARGE, + CANCELLER_FLINCH, + CANCELLER_DISABLED, + CANCELLER_GRAVITY, + CANCELLER_HEAL_BLOCKED, + CANCELLER_TAUNTED, + CANCELLER_IMPRISONED, + CANCELLER_CONFUSED, + CANCELLER_PARALYSED, + CANCELLER_IN_LOVE, + CANCELLER_BIDE, + CANCELLER_THAW, + CANCELLER_POWDER_MOVE, + CANCELLER_POWDER_STATUS, + CANCELLER_THROAT_CHOP, + CANCELLER_END, + CANCELLER_PSYCHIC_TERRAIN, + CANCELLER_END2, }; u8 AtkCanceller_UnableToUseMove(void) @@ -2337,6 +2365,17 @@ u8 AtkCanceller_UnableToUseMove(void) } gBattleStruct->atkCancellerTracker++; break; + case CANCELLER_THROAT_CHOP: + if (gDisableStructs[gBattlerAttacker].throatChopTimer && gBattleMoves[gCurrentMove].flags & FLAG_SOUND) + { + gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = 1; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; case CANCELLER_END: break; } diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index f3be9925b1..e692255e63 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -8956,7 +8956,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_THROAT_CHOP] = { - .effect = EFFECT_PLACEHOLDER, + .effect = EFFECT_THROAT_CHOP, .power = 80, .type = TYPE_DARK, .accuracy = 100,