diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index d986dec8cc..511299a11d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -347,6 +347,9 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectVCreate .4byte BattleScript_EffectMatBlock .4byte BattleScript_EffectStompingTantrum + .4byte BattleScript_EffectPlaceholder + .4byte BattleScript_EffectPlaceholder + .4byte BattleScript_EffectThroatChop BattleScript_EffectVCreate: setmoveeffect MOVE_EFFECT_V_CREATE | MOVE_EFFECT_AFFECTS_USER @@ -1673,7 +1676,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 @@ -5379,7 +5387,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 1f66b160b4..e80dcbba6a 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -302,5 +302,9 @@ extern const u8 BattleScript_VCreateStatLoss[]; extern const u8 BattleScript_SpikyShieldEffect[]; extern const u8 BattleScript_FlowerVeilProtectsRet[]; extern const u8 BattleScript_SweetVeilProtectsRet[]; +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 7d34f831f3..3761a5d875 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -328,6 +328,8 @@ #define MOVE_EFFECT_SPECTRAL_THIEF 0x3F #define MOVE_EFFECT_V_CREATE 0x40 #define MOVE_EFFECT_HAPPY_HOUR 0x41 + +#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 7a11f9b14f..a250decd6f 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -336,4 +336,7 @@ #define EFFECT_MAT_BLOCK 330 #define EFFECT_STOMPING_TANTRUM 331 + +#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 d6dc13ef4b..0694d22e52 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 eac5a24bb2..b0ed189bd8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2809,6 +2809,10 @@ void SetMoveEffect(bool32 primary, u32 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_VCreateStatLoss; 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 024a122023..aa6a7efc8a 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 5d89e7027c..fe3b7cbc31 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,