From e5e45bbcf57c943ea7c4c7f0ce51795cd469de82 Mon Sep 17 00:00:00 2001 From: Papa Cancer Date: Tue, 16 Apr 2019 14:01:48 +0100 Subject: [PATCH] Throat Chop Added strings that show when Throat Chop prevents move usage. Added extra string (not present in games) to show when it ends as there is no indication otherwise. Fixed Embargo's string as well. --- data/battle_scripts_1.s | 28 ++++++++- include/battle.h | 2 + include/battle_scripts.h | 4 ++ include/constants/battle.h | 2 + include/constants/battle_move_effects.h | 3 + include/constants/battle_string_ids.h | 5 +- src/battle_main.c | 1 + src/battle_message.c | 7 ++- src/battle_script_commands.c | 4 ++ src/battle_util.c | 83 ++++++++++++++++++------- src/data/battle_moves.h | 2 +- 11 files changed, 115 insertions(+), 26 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index d986dec8c..511299a11 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 8e74501a1..c6cf49fc2 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 1f66b160b..e80dcbba6 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 7d34f831f..3761a5d87 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 7a11f9b14..a250decd6 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 5114102f7..b4a408ca2 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 695be6470..bca4f26a7 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 d6dc13ef4..0694d22e5 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 eac5a24bb..b0ed189bd 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 024a12202..aa6a7efc8 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 5d89e7027..fe3b7cbc3 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,