Fixes Dragon Tail missing timing against Rocky Helmet / Iron Barbs (#6154)

This commit is contained in:
Alex 2025-01-31 22:02:26 +01:00 committed by GitHub
parent c5c22a0005
commit 97d8bd2646
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 109 additions and 39 deletions

View File

@ -1721,11 +1721,6 @@
.4byte \failInstr
.endm
.macro tryhitswitchtarget failInstr:req
callnative BS_TryHitSwitchTarget
.4byte \failInstr
.endm
.macro setmagiccoattarget
callnative BS_SetMagicCoatTarget
.endm

View File

@ -1798,25 +1798,17 @@ BattleScript_EffectFinalGambit::
jumpifmovehadnoeffect BattleScript_MoveEnd
goto BattleScript_MoveEnd
BattleScript_EffectHitSwitchTarget::
call BattleScript_EffectHit_Ret
tryfaintmon BS_TARGET
jumpiffainted BS_TARGET, TRUE, BattleScript_MoveEnd
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_MoveEnd
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
jumpiftargetdynamaxed BattleScript_HitSwitchTargetDynamaxed
tryhitswitchtarget BattleScript_MoveEnd
BattleScript_TryHitSwitchTarget::
forcerandomswitch BattleScript_HitSwitchTargetForceRandomSwitchFailed
goto BattleScript_MoveEnd
return
BattleScript_HitSwitchTargetDynamaxed:
BattleScript_HitSwitchTargetDynamaxed::
printstring STRINGID_MOVEBLOCKEDBYDYNAMAX
waitmessage B_WAIT_TIME_LONG
BattleScript_HitSwitchTargetForceRandomSwitchFailed:
hitswitchtargetfailed
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
goto BattleScript_MoveEnd
return
BattleScript_EffectToxicThread::
setstatchanger STAT_SPEED, 1, TRUE
@ -6774,6 +6766,12 @@ BattleScript_PrintMonIsRooted::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_PrintMonIsRootedRet::
pause B_WAIT_TIME_SHORT
printstring STRINGID_PKMNANCHOREDITSELF
waitmessage B_WAIT_TIME_LONG
return
BattleScript_AtkDefDown::
setbyte sSTAT_ANIM_PLAYED, FALSE
playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_ATK, STAT_CHANGE_CANT_PREVENT | STAT_CHANGE_NEGATIVE | STAT_CHANGE_MULTIPLE_STATS
@ -8261,6 +8259,13 @@ BattleScript_AbilityPreventsPhasingOut::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_AbilityPreventsPhasingOutRet::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_PKMNANCHORSITSELFWITH
waitmessage B_WAIT_TIME_LONG
return
BattleScript_AbilityNoStatLoss::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp

View File

@ -770,7 +770,10 @@ extern const u8 BattleScript_EffectDefenseUp3[];
extern const u8 BattleScript_EffectNobleRoar[];
extern const u8 BattleScript_EffectVenomDrench[];
extern const u8 BattleScript_EffectToxicThread[];
extern const u8 BattleScript_EffectHitSwitchTarget[];
extern const u8 BattleScript_TryHitSwitchTarget[];
extern const u8 BattleScript_HitSwitchTargetDynamaxed[];
extern const u8 BattleScript_AbilityPreventsPhasingOutRet[];
extern const u8 BattleScript_PrintMonIsRootedRet[];
extern const u8 BattleScript_EffectFinalGambit[];
extern const u8 BattleScript_EffectAutotomize[];
extern const u8 BattleScript_EffectCopycat[];

View File

@ -276,6 +276,7 @@ enum MoveEndEffects
MOVEEND_ITEM_EFFECTS_TARGET,
MOVEEND_MOVE_EFFECTS2,
MOVEEND_ITEM_EFFECTS_ALL,
MOVEEND_HIT_SWITCH_TARGET,
MOVEEND_KINGSROCK, // These item effects will occur each strike of a multi-hit move
MOVEEND_NUM_HITS,
MOVEEND_SUBSTITUTE,

View File

@ -6077,6 +6077,43 @@ static void Cmd_moveend(void)
else
gBattleScripting.moveendState++;
break;
case MOVEEND_HIT_SWITCH_TARGET:
if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_SWITCH_TARGET
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& TARGET_TURN_DAMAGED
&& IsBattlerAlive(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT)
{
u32 targetAbility = GetBattlerAbility(gBattlerTarget);
if (targetAbility == ABILITY_GUARD_DOG)
{
gBattleScripting.moveendState++;
break;
}
effect = TRUE;
BattleScriptPushCursor();
if (targetAbility == ABILITY_SUCTION_CUPS)
{
gBattlescriptCurrInstr = BattleScript_AbilityPreventsPhasingOutRet;
}
else if (gStatuses3[gBattlerTarget] & STATUS3_ROOTED)
{
gBattlescriptCurrInstr = BattleScript_PrintMonIsRootedRet;
}
else if (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX)
{
gBattlescriptCurrInstr = BattleScript_HitSwitchTargetDynamaxed;
}
else
{
gBattleScripting.switchCase = B_SWITCH_HIT;
gBattlescriptCurrInstr = BattleScript_TryHitSwitchTarget;
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_KINGSROCK: // King's rock
// These effects will occur at each hit in a multi-strike move
if (ItemBattleEffects(ITEMEFFECT_KINGSROCK, 0, FALSE))
@ -17381,26 +17418,6 @@ void BS_JumpIfBlockedBySoundproof(void)
}
}
void BS_TryHitSwitchTarget(void)
{
NATIVE_ARGS(const u8 *failInstr);
if (IsBattlerAlive(gBattlerAttacker)
&& IsBattlerAlive(gBattlerTarget)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& TARGET_TURN_DAMAGED
&& gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT
&& GetBattlerAbility(gBattlerTarget) != ABILITY_GUARD_DOG)
{
gBattleScripting.switchCase = B_SWITCH_HIT;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
gBattlescriptCurrInstr = cmd->failInstr;
}
}
void BS_SetMagicCoatTarget(void)
{
NATIVE_ARGS();

View File

@ -1571,7 +1571,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_HIT_SWITCH_TARGET] =
{
.battleScript = BattleScript_EffectHitSwitchTarget,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 0, // TODO: Assign points
},

View File

@ -69,3 +69,52 @@ SINGLE_BATTLE_TEST("Dragon Tail does not fail if replacements fainted")
NOT MESSAGE("But it failed!");
}
}
SINGLE_BATTLE_TEST("Dragon Tail switches the target after Rocky Helmet and Iron Barbs")
{
PASSES_RANDOMLY(1, 2, RNG_FORCE_RANDOM_SWITCH);
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_TOGEDEMARU) { Ability(ABILITY_IRON_BARBS); Item(ITEM_ROCKY_HELMET); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_CHARMANDER);
} WHEN {
TURN { MOVE(player, MOVE_DRAGON_TAIL); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player);
HP_BAR(player);
MESSAGE("Wobbuffet was hurt by the opposing Togedemaru's Iron Barbs!");
HP_BAR(player);
MESSAGE("Wobbuffet was hurt by the opposing Togedemaru's Rocky Helmet!");
MESSAGE("The opposing Charmander was dragged out!");
}
}
SINGLE_BATTLE_TEST("Dragon Tail effect will fails against Guard Dog ability")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_OKIDOGI) { Ability(ABILITY_GUARD_DOG); }
OPPONENT(SPECIES_CHARMANDER);
} WHEN {
TURN { MOVE(player, MOVE_DRAGON_TAIL); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player);
NOT MESSAGE("The opposing Charmander was dragged out!");
}
}
SINGLE_BATTLE_TEST("Dragon Tail effect will fails against Suction Cups ability")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_OCTILLERY) { Ability(ABILITY_SUCTION_CUPS); }
OPPONENT(SPECIES_CHARMANDER);
} WHEN {
TURN { MOVE(player, MOVE_DRAGON_TAIL); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player);
MESSAGE("The opposing Octillery anchors itself with Suction Cups!");
NOT MESSAGE("The opposing Charmander was dragged out!");
}
}