Fixes Cotton Spore failing if one of the targets blocks it (#6418)

Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
Co-authored-by: DizzyEggg <jajkodizzy@wp.pl>
This commit is contained in:
Alex 2025-03-18 15:41:37 +01:00 committed by GitHub
parent f237b5fa1b
commit 4193963096
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 24 deletions

View File

@ -129,7 +129,6 @@ enum
CANCELLER_STANCE_CHANGE_2,
CANCELLER_WEATHER_PRIMAL,
CANCELLER_DYNAMAX_BLOCKED,
CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS,
CANCELLER_PROTEAN,
CANCELLER_PSYCHIC_TERRAIN,
@ -348,5 +347,6 @@ bool32 IsPursuitTargetSet(void);
void ClearPursuitValuesIfSet(u32 battler);
void ClearPursuitValues(void);
bool32 HasWeatherEffect(void);
bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -1199,6 +1199,8 @@ static void Cmd_attackcanceler(void)
return;
if (gMovesInfo[gCurrentMove].effect == EFFECT_PARALYZE && AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, gCurrentMove))
return;
if (IsMovePowderBlocked(gBattlerAttacker, gBattlerTarget, gCurrentMove))
return;
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE
&& !(gHitMarker & (HITMARKER_ALLOW_NO_PP | HITMARKER_NO_ATTACKSTRING | HITMARKER_NO_PPDEDUCT))

View File

@ -3588,28 +3588,6 @@ static void CancellerDynamaxBlocked(u32 *effect)
}
}
static void CancellerPowderMove(u32 *effect)
{
if (IsPowderMove(gCurrentMove) && (gBattlerAttacker != gBattlerTarget))
{
if (B_POWDER_GRASS >= GEN_6
&& (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) || GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT))
{
gBattlerAbility = gBattlerTarget;
*effect = 1;
}
else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES)
{
RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES);
gLastUsedItem = gBattleMons[gBattlerTarget].item;
*effect = 1;
}
if (*effect != 0)
gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect;
}
}
static void CancellerPowderStatus(u32 *effect)
{
if (TryActivatePowderStatus(gCurrentMove))
@ -3842,7 +3820,6 @@ static const MoveSuccessOrderCancellers sMoveSuccessOrderCancellers[] =
[CANCELLER_STANCE_CHANGE_2] = CancellerStanceChangeTwo,
[CANCELLER_WEATHER_PRIMAL] = CancellerWeatherPrimal,
[CANCELLER_DYNAMAX_BLOCKED] = CancellerDynamaxBlocked,
[CANCELLER_POWDER_MOVE] = CancellerPowderMove,
[CANCELLER_POWDER_STATUS] = CancellerPowderStatus,
[CANCELLER_PROTEAN] = CancellerProtean,
[CANCELLER_PSYCHIC_TERRAIN] = CancellerPsychicTerrain,
@ -12295,3 +12272,30 @@ bool32 HasWeatherEffect(void)
return FALSE;
return TRUE;
}
bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move)
{
bool32 effect = FALSE;
if (IsPowderMove(move) && (battlerAtk != battlerDef))
{
if (B_POWDER_GRASS >= GEN_6
&& (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) || GetBattlerAbility(battlerDef) == ABILITY_OVERCOAT))
{
gBattlerAbility = battlerDef;
RecordAbilityBattle(gBattlerTarget, ABILITY_OVERCOAT);
effect = TRUE;
}
else if (GetBattlerHoldEffect(battlerDef, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES)
{
RecordItemEffectBattle(battlerDef, HOLD_EFFECT_SAFETY_GOGGLES);
gLastUsedItem = gBattleMons[battlerDef].item;
effect = TRUE;
}
if (effect)
gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect;
}
return effect;
}

View File

@ -0,0 +1,31 @@
#include "global.h"
#include "test/battle.h"
DOUBLE_BATTLE_TEST("Speed Down: Cotton Spore does not fail if it is blocked by one target")
{
u32 abilityOne, abilityTwo;
PARAMETRIZE { abilityOne = ABILITY_OVERCOAT; abilityTwo = ABILITY_SKILL_LINK; }
PARAMETRIZE { abilityOne = ABILITY_SKILL_LINK; abilityTwo = ABILITY_OVERCOAT; }
GIVEN {
ASSUME(GetMoveEffect(MOVE_COTTON_SPORE) == EFFECT_SPEED_DOWN_2);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SHELLDER) { Ability(abilityOne); }
OPPONENT(SPECIES_SHELLDER) { Ability(abilityTwo); }
} WHEN {
TURN { MOVE(playerLeft, MOVE_COTTON_SPORE); }
} SCENE {
if (abilityOne == ABILITY_OVERCOAT) {
ABILITY_POPUP(opponentLeft, ABILITY_OVERCOAT);
ANIMATION(ANIM_TYPE_MOVE, MOVE_COTTON_SPORE, playerLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
}
else if (abilityTwo == ABILITY_OVERCOAT) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_COTTON_SPORE, playerLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
ABILITY_POPUP(opponentRight, ABILITY_OVERCOAT);
}
}
}