Fix Redirection Abilities Not Drawing in Ally Moves (#6026)

Co-authored-by: ghoulslash <pokevoyager0@gmail.com>
This commit is contained in:
ghoulslash 2025-01-15 09:20:31 -05:00 committed by GitHub
parent 1c3ce75a60
commit fd26d3a406
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 66 additions and 22 deletions

View File

@ -142,6 +142,7 @@
#define B_SYMBIOSIS_GEMS GEN_LATEST // In Gen7+, Symbiosis passes an item after a gem-boosted attack. Previously, items are passed before the gem-boosted attack hits, making the item effect apply.
#define B_ABSORBING_ABILITY_STRING GEN_LATEST // In Gen5+, the abilities that absorb moves of a certain type use a generic string for stat increases and decreases.
#define B_REDIRECT_ABILITY_IMMUNITY GEN_LATEST // In Gen5+, Pokémon with Lightning Rod/Storm Drain become immune to Electric/Water-type moves and increase their Sp. Attack by 1 stage on top of the redirecting effect.
#define B_REDIRECT_ABILITY_ALLIES GEN_LATEST // In Gen4+, Lightning Rod/Storm Drain redirect ally's moves as well.
#define B_LEAF_GUARD_PREVENTS_REST GEN_LATEST // In Gen5+, Leaf Guard prevents the use of Rest in harsh sunlight.
#define B_SNOW_WARNING GEN_LATEST // In Gen9+, Snow Warning will summon snow instead of hail.
#define B_TRANSISTOR_BOOST GEN_LATEST // In Gen9+, Transistor will only boost Electric-type moves by 1.3x as opposed to 1.5x.

View File

@ -126,7 +126,7 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
// Functions
void HandleAction_UseMove(void)
{
u32 battler, i, side, moveType, var = 4;
u32 battler, i, side, moveType, ability, var = MAX_BATTLERS_COUNT;
u16 moveTarget;
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
@ -217,6 +217,7 @@ void HandleAction_UseMove(void)
// choose target
side = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker));
ability = GetBattlerAbility(gBattleStruct->moveTarget[gBattlerAttacker]);
if (IsAffectedByFollowMe(gBattlerAttacker, side, gCurrentMove)
&& moveTarget == MOVE_TARGET_SELECTED
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gSideTimers[side].followmeTarget))
@ -226,16 +227,18 @@ void HandleAction_UseMove(void)
else if (IsDoubleBattle()
&& gSideTimers[side].followmeTimer == 0
&& (!IS_MOVE_STATUS(gCurrentMove) || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS))
&& ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
&& ((ability != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (ability != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
{
side = GetBattlerSide(gBattlerAttacker);
// Find first battler that redirects the move (in turn order)
for (battler = 0; battler < gBattlersCount; battler++)
{
if (side != GetBattlerSide(battler)
&& *(gBattleStruct->moveTarget + gBattlerAttacker) != battler
&& ((GetBattlerAbility(battler) == ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (GetBattlerAbility(battler) == ABILITY_STORM_DRAIN && moveType == TYPE_WATER))
ability = GetBattlerAbility(battler);
if ((B_REDIRECT_ABILITY_ALLIES >= GEN_4 || !IsAlly(gBattlerAttacker, battler))
&& battler != gBattlerAttacker
&& gBattleStruct->moveTarget[gBattlerAttacker] != battler
&& ((ability == ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (ability == ABILITY_STORM_DRAIN && moveType == TYPE_WATER))
&& GetBattlerTurnOrderNum(battler) < var
&& gMovesInfo[gCurrentMove].effect != EFFECT_SNIPE_SHOT
&& gMovesInfo[gCurrentMove].effect != EFFECT_PLEDGE
@ -245,7 +248,7 @@ void HandleAction_UseMove(void)
var = GetBattlerTurnOrderNum(battler);
}
}
if (var == 4)
if (var == MAX_BATTLERS_COUNT)
{
if (moveTarget & MOVE_TARGET_RANDOM)
{
@ -8446,22 +8449,36 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
}
else
{
u32 battlerAbilityOnField = 0;
targetBattler = SetRandomTarget(gBattlerAttacker);
if (moveType == TYPE_ELECTRIC
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD)
&& GetBattlerAbility(targetBattler) != ABILITY_LIGHTNING_ROD)
if (moveType == TYPE_ELECTRIC && GetBattlerAbility(targetBattler) != ABILITY_LIGHTNING_ROD)
{
targetBattler ^= BIT_FLANK;
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
gSpecialStatuses[targetBattler].lightningRodRedirected = TRUE;
if (B_REDIRECT_ABILITY_ALLIES >= GEN_4)
battlerAbilityOnField = IsAbilityOnField(ABILITY_LIGHTNING_ROD);
else
battlerAbilityOnField = IsAbilityOnOpposingSide(targetBattler, ABILITY_LIGHTNING_ROD);
if (battlerAbilityOnField > 0)
{
targetBattler = battlerAbilityOnField - 1;
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
gSpecialStatuses[targetBattler].lightningRodRedirected = TRUE;
}
}
else if (moveType == TYPE_WATER
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN)
&& GetBattlerAbility(targetBattler) != ABILITY_STORM_DRAIN)
else if (moveType == TYPE_WATER && GetBattlerAbility(targetBattler) != ABILITY_STORM_DRAIN)
{
targetBattler ^= BIT_FLANK;
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
gSpecialStatuses[targetBattler].stormDrainRedirected = TRUE;
if (B_REDIRECT_ABILITY_ALLIES >= GEN_4)
battlerAbilityOnField = IsAbilityOnField(ABILITY_STORM_DRAIN);
else
battlerAbilityOnField = IsAbilityOnOpposingSide(targetBattler, ABILITY_STORM_DRAIN);
if (battlerAbilityOnField > 0)
{
targetBattler = battlerAbilityOnField - 1;
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
gSpecialStatuses[targetBattler].lightningRodRedirected = TRUE;
}
}
}
break;

View File

@ -71,3 +71,29 @@ DOUBLE_BATTLE_TEST("Lightning Rod forces single-target Electric-type moves to ta
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
}
}
DOUBLE_BATTLE_TEST("Lightning Rod redirects an ally's attack")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponentRight, MOVE_THUNDERBOLT, target: playerLeft); }
} SCENE {
MESSAGE("The opposing Wobbuffet used Thunderbolt!");
if (B_REDIRECT_ABILITY_ALLIES >= GEN_5)
{
NOT HP_BAR(playerLeft);
ABILITY_POPUP(opponentLeft, ABILITY_LIGHTNING_ROD);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
MESSAGE("The opposing Raichu's Sp. Atk rose!");
}
else
{
HP_BAR(playerLeft);
}
}
}

View File

@ -886,7 +886,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move
{
GIVEN {
ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
PLAYER(SPECIES_MAROWAK) { Ability(ABILITY_LIGHTNING_ROD); }
PLAYER(SPECIES_ELECTIVIRE) { Ability(ABILITY_MOTOR_DRIVE); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);